Announcement Announcement Module
Collapse
No announcement yet.
How to resolve LazyInitializationException's by always fetching EAGER? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to resolve LazyInitializationException's by always fetching EAGER?

    Hi all,

    I'm trying to resolve my LazyInitializationException's by always fetching eagerly.

    I've got a bidirectional relationship between my Person and Vehicle classes:

    Person with OneToMany to Vehicle:

    PHP Code:
    @Entity
    @Table(name "person")
    public class 
    Person {
        
        
    //Fields
        
    private Long id;
        private 
    String name;
        private 
    Date birthDate;
        private 
    Set<Vehiclevehicles = new HashSet<Vehicle>();
        

        
    //Property accessors
        
    @Id
        
    @GeneratedValue(strategy IDENTITY)
        @
    Column(name "id"unique truenullable false)
        public 
    Long getId() {
            return 
    this.id;
        }

        public 
    void setId(Long id) {
    System.out.println("in java Person-> setId = "+id);
            
    this.id id;
        }

        @
    Column(name "Name"nullable falselength 35)
        public 
    String getName() {
            return 
    this.name;
        }

        public 
    void setName(String name) {
    System.out.println("in java Person-> setName = "+name);    
            
    this.name name;
        }    
        
        @
    Temporal(TemporalType.DATE)
        @
    Column(name "BirthDate"nullable truelength 10)
        public 
    Date getBirthDate() {
            return 
    this.birthDate;
        }

        public 
    void setBirthDate(Date birthDate) {
            
    this.birthDate birthDate;
        }    
                
        @
    CollectionOfElements(targetElement be.tradelec.model.Vehicle.class)
        @
    OneToMany(mappedBy "person_id"cascade=CascadeType.ALLfetch=FetchType.EAGER)
        public 
    Set<VehiclegetVehicles() {
            return 
    vehicles;
        }        
        
        public 
    void setVehicles(Set<Vehiclevehicles) {
    System.out.println("in java Person-> setVehicles = "+vehicles);
            
    this.vehicles vehicles;
        }
        
        public 
    void addVehicle(Vehicle vehicle) {
            
    vehicles.add(vehicle);
            
    vehicle.setPerson(this);
        }
        

    Vehicle with ManyToOne to Peron:

    PHP Code:
    @Entity
    @Table(name "vehicle")
    public class 
    Vehicle {

        
    // Fields
        
    private Long id;    
        private 
    Long person_id;     
        private 
    Person person;    
        private 
    String licensePlate;
        private 
    String brand;
        private 
    String type;
        
        
    // Constructors
        /** default constructor */
        
    public Vehicle() {
        }

        
    /** full constructor */
        
    public Vehicle(Long idPerson person,
                
    String licensePlateString brandString type) {
            
    this.id id;
            
    //this.person = person;
            
    this.licensePlate licensePlate;
            
    this.brand brand;
            
    this.type type;
        }
        
        
    // Property accessors
        
    @Id
        
    @GeneratedValue(strategy GenerationType.AUTO)
        @
    Column(name "id"unique truenullable false)
        public 
    Long getId() {
            return 
    this.id;
        }

        public 
    void setId(Long id) {
            
    System.out.println("in java Vehicle-> setIdVehicle = "+id);
            
    this.id id;
        }
            
        @
    CollectionOfElements(targetElement be.tradelec.model.Person.class)
        @
    ManyToOne(fetch=FetchType.EAGER)
        @
    JoinColumn(name "person_id")
        public 
    Person getPerson() {
            return 
    this.person;
        }

        public 
    void setPerson(Person person) {
            
    this.person person;
        }

        @
    Column(name "LicensePlate"nullable truelength 10)
        public 
    String getLicensePlate() {
            return 
    this.licensePlate;
        }

        public 
    void setLicensePlate(String licensePlate) {
            
    this.licensePlate licensePlate;
        }

        @
    Column(updatable=falseinsertable=false)
        public 
    Long getPerson_id() {
            return 
    person_id;
        }

        public 
    void setPerson_id(Long person_id) {
            
    this.person_id person_id;
        }

        @
    Column(name "Brand"nullable falselength 45)
        public 
    String getBrand() {
            return 
    this.brand;
        }

        public 
    void setBrand(String brand) {
            
    this.brand brand;
        }

        @
    Column(name "Type"nullable falselength 45)
        public 
    String getType() {
            return 
    this.type;
        }

        public 
    void setType(String type) {
            
    this.type type;
        }


    Saving a Person with added Vehicles works nicely. And with standard fetchtypes I can load my Person (with his vehicles) perfectly.

    Now when I try to switch both my mappings to EAGER fetchtypes so I can send the whole Object graph through BlazeDS, I get an error while loading:

    PHP Code:
    Hibernateselect person0_.id as id4_1_person0_.BirthDate as BirthDate4_1_person0_.Name as Name4_1_vehicles1_.person_id as person4_3_vehicles1_.id as id3_vehicles1_.id as id5_0_vehicles1_.Brand as Brand5_0_vehicles1_.LicensePlate as LicenseP3_5_0_vehicles1_.person_id as person4_5_0_vehicles1_.Type as Type5_0_ from person person0_ left outer join vehicle vehicles1_ on person0_.id=vehicles1_.person_id where person0_.id=?
    in java Vehicle-> setIdVehicle 1
    in java Person
    -> setId 1
    in java Vehicle
    -> setIdVehicle 2
    in java Person
    -> setName Jochen
    17
    -jun-2009 10:30:06 org.hibernate.LazyInitializationException <init>
    SEVEREillegal access to loading collection
    org
    .hibernate.LazyInitializationExceptionillegal access to loading collection
        at org
    .hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
    ... 
    Last edited by Dr.Drane; Jun 17th, 2009, 06:31 AM.

  • #2
    I don't know if this can be, but why use both annotation, one-to-many and CollectionOfElements. Documentation say that CollectionOfElements it's replacement for one-to-many.
    Second, in relation many-to-one, i don't think that it's right to use CollectionOfElements, because in class Vehicle, person it's an object not an collection.
    Try to change that, and see how it's work.

    Comment


    • #3
      Originally posted by vlad2005 View Post
      I don't know if this can be, but why use both annotation, one-to-many and CollectionOfElements. Documentation say that CollectionOfElements it's replacement for one-to-many.
      Second, in relation many-to-one, i don't think that it's right to use CollectionOfElements, because in class Vehicle, person it's an object not an collection.
      Try to change that, and see how it's work.
      Oh I see. Makes a lot of sense!
      I used collection of elements because I had some kind of problem that seemed like Hibernate not knowing what kind of object I was mapping to. So I used it to make it clear what kind of object I was mapping to. But I think you might be right since it normally is used for non entity to entity mapping I guess.

      Will try it tomorrow. Thank you very very much for being so kind to give me some advice!

      Have a nice day.

      Kind regards,

      Jochen

      Comment


      • #4
        Probably, u have an bean that instantiate sessionFactory, where u set all hibernate parameters. There need to map and java classes. Personally, i use annotation, because it's more convenient, and i have an tag like this inside sessionFactory bean:
        Code:
        <property name="packagesToScan" value="spa.domain"/>
        In this mode, i don't need to map every class. Spring scan for me .

        Comment


        • #5
          I forgot, but if u want to specify what entity are mapped, u can use "targetEntity" property. Declaration for for @OneToMany it's:
          Code:
          public @interface OneToMany {
               Class targetEntity() default void.class;
               CascadeType []cascade() default {};
               FetchType []fetch() default EAGER;
               String mappedBy() default "";
           }
          Same idea for ManyToOne
          Code:
          public @interface ManyToOne {
               Class targetEntity() default void.class;
               CascadeType []cascade() default {};
               FetchType []fetch() default EAGER;
               boolean optional() default true;
           }

          Comment


          • #6
            w00h00w! Thanks a lot vlad2005!

            With you response I managed to solve the issue.
            Apparently it was associated with me printing out the value of my vehicles variable:

            PHP Code:
            public void setVehicles(Set<Vehiclevehicles) {
            //System.out.println("in java Person-> setVehicles = "+vehicles); 
            That also explains the "SEVERE: illegal access to loading collection"...i was trying to print out something before it was loaded actually.

            And also many thanks for the "packagesToScan" tip!! Very handy since I still was using the annoying-to-manage "annotatedClasses" property:
            PHP Code:
            <property name="annotatedClasses">
                        <list>
                            <
            value>com.prefabsoft.model.Article</value
            So big thumbs up for your help! You made my (fri)day feeling like already being weekend.

            Greets,

            Jochen

            Comment


            • #7
              you're welcome!

              Comment

              Working...
              X