4 Replies Latest reply on Nov 27, 2007 5:25 AM by markusdöring

    Getter for LAZY property gets called on every commit

    markusdöring

      Hello,
      First of all, i'm working with JBoss 4.2.0 GA and MySQL 5.
      I have the following code for my EntityBeans:

      EntityBean1

      @Entity
      public class EntityBean1 {
       private long id;
      
       private byte[] data;
      
       private boolean active;
      
       private EntityBean2 relation;
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public long getId() {return this.id;}
      
       public void setId(long id) {this.id = id;}
      
       public boolean isActive() {return this.active;}
      
       public boolean setActive(boolean active) {this.active = active;}
      
       @Lob
       @Column(columnDefinition = "LONGBLOB")
       @Basic(fetch = FetchType.LAZY)
       public byte[] getData() {
       log.debug("getData called");
       return this.data;
       }
      
       public void setData(byte[] data) { this.data = data;}
      
       @ManyToOne
       public EntityBean2 getRelation() {return this.relation;}
      
       public void setRelation(EntityBean2 relation) {this.relation = relation;}
      }


      EntityBean2
      @Entity
      public class EntityBean2 {
       private long id;
      
       private List<EntityBean1> relation;
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public long getId() {return this.id;}
      
       public void setId(long id) {this.id = id;}
      
       @OneToMany(mappedBy = "relation", cascade = cascadeType.ALL)
       public List<EntityBean1> getRelation() {return this.relation;}
      
       public void setRelation(List<EntityBean1> relation) {this.relation = relation;}
      }


      SomeStatelessSessionBean
      @Stateless
      public class SomeStatelessSessionBean implements SomeStatelessSessionLocal {
      
       public List<EntityBean1> doSomething() {
       log.debug("doSomething started");
       List<EntityBean1> out = new ArrayList<EntityBean1>();
       EntityBean2 bean2 = someFinder();
       for(EntityBean1 bean1 = bean2.getRelation()) {
       if(bean1.isActive()) {
       out.add(bean1);
       }
       }
       log.debug("doSomething ended");
       return out;
       }
      }


      What i do is calling the doSomething() methode from somehwere with a log.debug("start"); before and a log.debug("end"); directly after the methode call.

      What i get is the following log:
       XXX DEBUG start
       XXX DEBUG doSomething started
       XXX DEBUG doSomething ended
       XXX DEBUG getData called
       XXX DEBUG getData called
       XXX DEBUG getData called
       XXX DEBUG getData called
       XXX DEBUG getData called
       XXX DEBUG end
      



      What does this means?
      As far as i can see, when the transaction from doSomething() is commited, the getData() methode of the EntityBean1 get called. This should NOT be the case, because it is set to LAZY and i NEVER use the byte[] in this case.

      My problem is that the byte[] might be large, and at some point, i get an OOMException: heapSize. I've done a HeapDump and saw LOTS of byte[] in the memory, that's how i found this strange behavier. I also checkt if the getData() get's called by the equals() or hashCode() methode of EntityBean1, but this is not the case.

      Is this a bug in EJB3 (hibernate?) or is something "wrong" with my code? Or is it working as designed and there are no "real" lazy byte[] propertys?

      Thanks for help