I'm having a strange issue with Spring and Hibernate when running multiple threads in an application. I'm using spring 3.2.0.RELEASE and hibernate 4.1.12.Final. The issue is that for some objects, when they are retrieved from the db, the retrieval succeeds, but all mapped collections are not being set. Here's an example of my repo:
@Repository("fooRepository")
public class FooRepository {
private static final Logger log = Logger.getLogger(FooRepository.class);
@Autowired
private SessionFactory sessionFactory;
@Override
@Transactional
public Foo retrieve(final Long id) {
Foo instance = (Foo) sessionFactory.getCurrentSession().get(Foo.class, id);
for (CollectionMember member : instance.getCollectionMembers()) {
log.debug(member.getId());
}
return instance;
}
For some objects, this method always throws the following error when trying to access the CollectionMember list:
Caused by: java.lang.NullPointerException
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:501)
The problem is that the session.get() call creates PersistentBag objects for all lazy loaded collections but never sets the content. This only occurs when multithreading is enabled. Can anybody explain why this is happening?
EDIT: Here's the relevant bit of the foo class:
@Entity
@Table(name = "FOO")
@XmlRootElement(name = "foo")
public class Foo {
@EmbeddedId
private FooPK id;
@OneToMany
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumns({
@JoinColumn(name = "COLLECTION_ID", referencedColumnName = "COLLECTION_ID"),
@JoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID")})
private List<CollectionMember> collectionMembers = new ArrayList<CollectionMember>();
And the CollectionMember class:
@Entity
@Table(name = "COLLECTION_MEMBER")
@XmlRootElement(name = "collectionMember")
public class CollectionMember {
@EmbeddedId
private CollectionMemberPK primaryKey;
@ManyToOne
@JoinColumn(name = "COLL_CODE")
private CollectionCode collectionCode;
I think you should use third join table like and use Criteria for loading collection.
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(name = "table", joinColumns = {@JoinColumn(name = "COLLECTION_ID", nullable = false)}, inverseJoinColumns = { @JoinColumn(name = "FOO_ID", nullable = true) })
private List<CollectionMember> collectionMembers = new ArrayList<CollectionMember>();
@ManyToOne(mappedBy="collectionMembers")
private CollectionCode collectionCode;
Problem is @NotFound(action = NotFoundAction.IGNORE)
This will create a returned object null instead of an empty collection in case no collection records are found. Remove and test it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With