Reputation: 8820
I though I understood lazy/eager loading, but obviously I don't:
I have a service that is marked @Transactional, yet when I try to manipulate the list I get (accessing its objects), I get "org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: tld.myproduct.data.entities.CategoryType.translatableText, no session or session was closed". Any suggestions to why I cannot access my under-objects?
UPDATE: The exception happens at the line "type.getTranslatableText().size()"
Cheers
Nik
// The service
@Service("categoryTypeService")
@Transactional("transactionManager")
public class CategoryTypeServiceImpl extends AbstractCRUDServiceImpl<CategoryType, Integer> implements CategoryTypeService {
@SuppressWarnings("unchecked")
@Override
public List<CategoryType> getAll() {
List<CategoryType> list = DAO.getSession().createCriteria(CategoryType.class).list();
for(CategoryType type : list)
type.getTranslatableText().size(); // Access TranslatableText to demonstrate problem
return list;
}
}
// The entity
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
@Configurable(preConstruction=true)
public class CategoryType {
@Id
@Column(nullable = false)
private Integer id;
@Column(length = 50, nullable = true)
private String description;
@Column(name = "TranslatableDescriptionId", nullable = false)
private Integer TranslatableDescriptionId;
@OneToMany(fetch=FetchType.LAZY)
@JoinColumn(name = "Id", referencedColumnName="TranslatableDescriptionId", insertable=false, updatable=false)
private Set<TranslatableText> translatableText;
/** getters and setters **/
}
Upvotes: 1
Views: 4970
Reputation: 66196
Here is a general discussion of Open Session in View issue. I recommend you to read the article.
To put is simple, you have 3 possible solutions:
1) don't do lazy loading of the collection (of course, if it's not critical, performance should be tested somehow):
@OneToMany(fetch=FetchType.EAGER) // <-- it's not lazy any more
@JoinColumn(name = "Id", referencedColumnName="TranslatableDescriptionId", insertable=false, updatable=false)
private Set<TranslatableText> translatableText;
2) you can use Open Session in View Filter (or OpenEntityManagerInViewFilter), but this will keep your session open until the page loading will be finished (maybe a few seconds).
It can cause performance issues, and more likely, you'll get the situation, when one user is changing objects while another user has an open hibernate session. I don't know exactly what happens then but you should find it out if you want to be sure that your application is robust.
3) when you need to load some collection from a DB just execute a JPA query and fetch all the necessary data with special DAO method (this means that field translatableText
will disappear from CategoryType
class). The most robust solution but you'll need to do some extra work to implement it, its more difficult then any of previous 2 options.
Upvotes: 2