Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException when accessing lazy loaded collection within DAO method

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;
like image 676
Rockenstein Avatar asked May 24 '13 21:05

Rockenstein


2 Answers

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;
like image 160
pankaj Avatar answered Sep 21 '22 09:09

pankaj


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

like image 26
Mahendra Avatar answered Sep 22 '22 09:09

Mahendra