LazyInitializationException when saving one side of a relationship

1k Views Asked by At

I have a class Patient that has a collection of Id, and a collection of Folders. When I try to save a Folder on its own it throws a LazyInitializationException because of the Patient's id collection.

Patient class looks like this:

@Entity
@Table(name = "patient")
public class Patient implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @OneToMany(mappedBy = "patient", fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
    private Set<Id> ids = new HashSet<Id>();

    @OneToMany(mappedBy = "patient", fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
    private List<Folder> folders = new ArrayList<Folder>();

    ...
}

Folder class looks like this:

@Entity
@Table(name = "folder")
public class Folder implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "patient_id", referencedColumnName = "id")
    private Patient patient;

}

Then I have a service class that does things and then saves a folder like this:

@Override
@Transactional
public void importData(Data data) {

    // do other things
    Folder folder = new Folder();
    // initialize folder values
    ...
    folder.setPatient(patient);
    folderDAO.save(folder);
    ...
}

And when it tries to save the folder in FolderDAO with:

getHibernateTemplate().saveOrUpdate(folder);

It throws:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: es.mycompany.myapp.Patient.ids, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:587)
2

There are 2 best solutions below

0
Ognjen Mišić On

The issue is that you're trying to saveOrUpdate outside of the session. Hibernate.initialize will initialize your Patient collection for use prior to your saveOrUpdate, or you can manually open a hibernate session, transaction, do commit and close the resources.

Try like this: https://www.mkyong.com/hibernate/hibernate-transaction-handle-example/

1
Mirko Ferranti On

with a cascade = ALL configuration, you are configuring hibernate to update the list/set of patient when the folder entity is saved, the patient list must be loaded in memory to be updated. You may be able to try to remove CASCADE = ALL and manually manage any list and set of patient class updates.