Прежде всего правильно сопоставьте двунаправленное отношение OneToMany. Вы должны иметь
@Entity
@Table(name = "singer")
public class SingerEntity {
...
@OneToMany(mappedBy = "singer", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AlbumEntity> albums;
...
}
@Entity
@Table(name = "album")
public class AlbumEntity {
...
@ManyToOne
@JoinColumn(name = "singer_id)
private SingerEntity singer;
....
}
Если вы хотите добавить альбом к объекту, лучше использовать пользовательский метод для объекта Singer, чтобы ссылки оставались правильными, например:
public void addAlbum(AlbumEntity a) {
albums.add(a);
a.setSinger(this);
}
После этого вы можете сохранять альбомы только для сохраняемого исполнителя, поскольку у вас есть опция Cascade.
Тогда, поскольку коллекция отношений OneToMany по умолчанию ленива, вы должны загрузить ее в ту же транзакцию, где вы получаете SingerEntity. Таким образом, SingerEntity будет присоединен к сеансу Hibernate. Например, вы можете использовать аннотацию Spring @Transactional для вашего метода.
Я не вижу ваш код DAO, но main может выглядеть так:
SingerDAO sDAO = new SingerDAO();
AlbumDAO aDAO = new AlbumDAO();
SingerEntity s1 = new SingerEntity(1,"Singer");
s1.addAlbum(new AlbumEntity(1,"a1","g1",1));
s1.addAlbum(new AlbumEntity(2,"a2","g2",1));
s1.addAlbum(new AlbumEntity(3,"a3","g3",1));
s1.addAlbum(new AlbumEntity(4,"a4","g4",1));
sDAO.insert(s1);
Измените findById, чтобы использовать одну транзакцию для отложенной загрузки:
public SingerEntity findById(int id) {
Session session = null;
SingerEntity singer = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
//start transaction
singer = (SingerEntity) session.get(SingerEntity.class, id);
Hibernate.initialize(singer);
//end transaction
} catch (Exception e){
e.printStackTrace();
} finally {
if (session != null && session.isOpen()){
session.close();
}
}
return singer;
}