1 Reply Latest reply on Sep 25, 2006 11:12 PM by jluv

    New Core bug?  FetchType.Eager does not work on collection w

    jluv

      I'm trying to eagerly load a Set of an entity that has an EmbeddedId. When I call EntityManager.find, it does not load the Set. When I change the embeddedId to be a regular Id, all is well. Am I doing something wrong, or should I log a new bug?

      I'm using Entity Manager 3.2.0 CR2, with Hibernate Core 3.2.0 CR4.

      Card:

      @Entity
      public class Card implements Serializable {
       @Id
       private String id;
      
       @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "card")
       private Set<CardField> fields;
      
       public Card(String id) {
       this();
       this.id = id;
      
       }
      
       Card() {
       fields = new HashSet<CardField>();
       }
      
       public String getId() {
       return id;
       }
      
       public void setId(String id) {
       this.id = id;
       }
      
       public void addField(Card card, Key key) {
       fields.add(new CardField(card, key));
       }
      
       @Override
       public int hashCode() {
       final int PRIME = 31;
       int result = 1;
       result = PRIME * result + ((id == null) ? 0 : id.hashCode());
       return result;
       }
      
       @Override
       public boolean equals(Object obj) {
       System.out.println("Equals invoked");
       System.exit(0);
       if (this == obj)
       return true;
       if (obj == null)
       return false;
       if (getClass() != obj.getClass())
       return false;
       final Card other = (Card) obj;
       if (id == null) {
       if (other.id != null)
       return false;
       } else if (!id.equals(other.id))
       return false;
       return true;
       }
      }
      


      CardField:
      @Entity
      public class CardField implements Serializable {
      
       private static final long serialVersionUID = 1L;
      
       private PrimaryKey primaryKey;
      
       private String id;
      
       CardField(Card card, Key key) {
       this.primaryKey = new PrimaryKey(card, key);
       }
      
       CardField() {
       }
      
       @Override
       public int hashCode() {
       final int PRIME = 31;
       int result = 1;
       result = PRIME * result + ((primaryKey == null) ? 0 : primaryKey.hashCode());
       return result;
       }
      
       @Override
       public boolean equals(Object obj) {
       System.out.println("Equals invoked");
       System.exit(0);
       if (this == obj)
       return true;
       if (obj == null)
       return false;
       if (getClass() != obj.getClass())
       return false;
       final CardField other = (CardField) obj;
       if (primaryKey == null) {
       if (other.primaryKey != null)
       return false;
       } else if (!primaryKey.equals(other.primaryKey))
       return false;
       return true;
       }
      
       @EmbeddedId
       public PrimaryKey getPrimaryKey() {
       return primaryKey;
       }
      
       public void setPrimaryKey(PrimaryKey primaryKey) {
       this.primaryKey = primaryKey;
       }
      
       // BEGIN Workaround until issue is resolved.
       // http://opensource.atlassian.com/projects/hibernate/browse/EJB-225
       @ManyToOne
       @JoinColumn(insertable=false, updatable=false)
       public Card getCard() {
       return primaryKey.getCard();
       }
      
       public void setCard(Card card) {
       primaryKey.setCard(card);
       }
      
       @ManyToOne
       @JoinColumn(insertable=false, updatable=false)
       public Key getKey() {
       return primaryKey.getKey();
       }
      
       public void setKey(Key key) {
       primaryKey.setKey(key);
       }
       // END Workaround
      }
      


      Changing CardField to use regular Id makes the Set in Card load eagerly:
      @Entity
      public class CardField implements Serializable {
      
       private static final long serialVersionUID = 1L;
      
       private PrimaryKey primaryKey;
      
       private String id;
      
       private Card card;
      
       private Key key;
      
       CardField(Card card, Key key) {
       this.primaryKey = new PrimaryKey(card, key);
       this.card = card;
       this.key = key;
       this.id = card.getId() + key.getId();
       }
      
       CardField() {
       }
      
       @Override
       public int hashCode() {
       final int PRIME = 31;
       int result = 1;
       result = PRIME * result + ((primaryKey == null) ? 0 : primaryKey.hashCode());
       return result;
       }
      
       @Override
       public boolean equals(Object obj) {
       System.out.println("Equals invoked");
       System.exit(0);
       if (this == obj)
       return true;
       if (obj == null)
       return false;
       if (getClass() != obj.getClass())
       return false;
       final CardField other = (CardField) obj;
       if (primaryKey == null) {
       if (other.primaryKey != null)
       return false;
       } else if (!primaryKey.equals(other.primaryKey))
       return false;
       return true;
       }
      
       //@EmbeddedId
       @Transient
       public PrimaryKey getPrimaryKey() {
       return primaryKey;
       }
      
       public void setPrimaryKey(PrimaryKey primaryKey) {
       this.primaryKey = primaryKey;
       }
      
       @Id
       public String getId() {
       return id;
       }
      
       public void setId(String id) {
       this.id = id;
       }
      
       @ManyToOne(optional = false)
       @JoinColumn(name="cardId")
       public Card getCard() {
       return card;
       }
      
       public void setCard(Card card) {
       this.card = card;
       }
      
       @ManyToOne(optional = false)
       @JoinColumn(name="keyId")
       public Key getKey() {
       return key;
       }
      
       public void setKey(Key key) {
       this.key = key;
       }
      }
      


        • 1. Re: New Core bug?  FetchType.Eager does not work on collecti
          jluv

          I've solved this problem. It was related to bug EJB-225.

          In the example above, the primary key class had a a reference to Card which was being loaded eagerly. I'm pretty sure the EJB3 spec says that the default should be lazy. Adding fetch=FetchType.LAZY to the mapping to Card in the primary key class also solved the problem described above.