Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: NullPointerException in StatefulPersistenceContext
PostPosted: Thu Aug 11, 2016 9:08 am 
Newbie

Joined: Thu Aug 11, 2016 8:56 am
Posts: 3
I've been trying to solve a problem with a NullPointerException in a Hibernate class when I set the fetch attribute of a @OneToMany field to FetchType.EAGER. I assume I'm doing something wrong but I can't see what, can anyone help?

This is the error:

Code:
Caused by: java.lang.NullPointerException
    at org.hibernate.engine.internal.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:780)
    at org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:58)
    at org.hibernate.event.spi.InitializeCollectionEvent.<init>(InitializeCollectionEvent.java:22)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2002)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:562)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:246)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:558)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:131)
    at org.hibernate.collection.internal.PersistentSet.toArray(PersistentSet.java:170)
    at testhib.entities.Parent.$$_hibernate_write_children(Parent.java)
    ... 64 more


This is the test case I've constructed:

Database

Code:
CREATE TABLE `test`.`parent` (
  `parent_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_version` int(10) unsigned NOT NULL DEFAULT '1',
  `parent_name` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`parent_id`)
);

CREATE TABLE `test`.`child` (
  `child_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `child_version` int(10) unsigned NOT NULL DEFAULT '1',
  `child_name` varchar(64) DEFAULT NULL,
  `child_parent` int(10) unsigned NOT NULL,
  PRIMARY KEY (`child_id`),
  KEY `fk_child_1_idx` (`child_parent`),
  CONSTRAINT `fk_child_1` FOREIGN KEY (`child_parent`) REFERENCES `parent` (`parent_id`)
);

INSERT INTO `test`.`parent`
(`parent_id`, `parent_name`)
VALUES
(1, 'Homer');

INSERT INTO `test`.`child`
(`child_id`, `child_name`, `child_parent`)
VALUES
(1, 'Bart', 1),
(2, 'Lisa', 1),
(3, 'Maggie', 1);


Entities

Code:
package testhib.entities;

import java.io.Serializable;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import static javax.persistence.FetchType.EAGER;

@Entity
@Table(name = "parent")
public class Parent implements Serializable {

    private static final long serialVersionUID = 1L;
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "parent_id")
    private Integer parentId;
   
    @Basic(optional = false)
    @Column(name = "parent_version")
    private int parentVersion;
   
    @Column(name = "parent_name")
    private String parentName;
   
    @OneToMany(mappedBy = "parent", fetch = EAGER)
    private Set<Child> children;

    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public int getParentVersion() {
        return parentVersion;
    }

    public void setParentVersion(int parentVersion) {
        this.parentVersion = parentVersion;
    }

    public String getParentName() {
        return parentName;
    }

    public void setParentName(String parentName) {
        this.parentName = parentName;
    }
   
    public Set<Child> getChildren() {
        return children;
    }
   
    public void setChildren(Set<Child> children) {
        this.children = children;
    }
}

package testhib.entities;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "child")
public class Child implements Serializable {

    private static final long serialVersionUID = 1L;
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "child_id")
    private Integer childId;
   
    @Basic(optional = false)
    @Column(name = "child_version")
    private int childVersion;
   
    @Column(name = "child_name")
    private String childName;
   
    @JoinColumn(name = "child_parent", referencedColumnName = "parent_id")
    @ManyToOne
    private Parent parent;

    public Integer getChildId() {
        return childId;
    }

    public void setChildId(Integer childId) {
        this.childId = childId;
    }

    public int getChildVersion() {
        return childVersion;
    }

    public void setChildVersion(int childVersion) {
        this.childVersion = childVersion;
    }

    public String getChildName() {
        return childName;
    }

    public void setChildName(String childName) {
        this.childName = childName;
    }
   
    public Parent getParent() {
        return parent;
    }
   
    public void setParent(Parent parent) {
        this.parent = parent;
    }
}


Test

Code:
package testhib.test;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import testhib.entities.Parent;

import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;

public class Tests {
   
    private static EntityManagerFactory emf;
    private EntityManager em;
   
    public Tests() {
    }
   
    @BeforeClass
    public static void setUpClass() {
       
        emf = Persistence.createEntityManagerFactory("test-hib");
    }
   
    @AfterClass
    public static void tearDownClass() {
       
        emf.close();
    }
   
    @Before
    public void setUp() {
       
        em = emf.createEntityManager();
       
        em.getTransaction().begin();
    }
   
    @After
    public void tearDown() {
       
        em.getTransaction().commit();
       
        em.close();
    }

    @Test
    public void canRead() {
       
        Parent p = em.find(Parent.class, 1);
       
        Set<String> names = new HashSet<>();
       
        p.getChildren().stream().forEach((c) -> {
           
            names.add(c.getChildName());
        });
       
        assertThat(names, containsInAnyOrder("Bart", "Lisa", "Maggie"));
    }
}


peristence.xml

Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="test-hib" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>testhib.entities.Parent</class>
    <class>testhib.entities.Child</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
      <property name="javax.persistence.jdbc.user" value="test"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.password" value="password"/>
    </properties>
  </persistence-unit>
</persistence>



POM

Code:
<?xml version="1.0" encoding="UTF-8"?>
<project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   
    <modelVersion>4.0.0</modelVersion>
    <groupId>uk.co.discoverdorset</groupId>
    <artifactId>test-hib</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
   
    <name>test-hib</name>
   
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
   
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>5.1.0.Final</version>
                <executions>
                    <execution>
                        <configuration>
                            <failOnError>true</failOnError>
                            <enableLazyInitialization>true</enableLazyInitialization>
                            <enableDirtyTracking>true</enableDirtyTracking>
                            <enableAssociationManagement>true</enableAssociationManagement>
                            <enableExtendedEnhancement>false</enableExtendedEnhancement>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
   
</project>


The test runs without a hitch if I comment out the "fetch = EAGER" from the Parent entity.

Any ideas?


Top
 Profile  
 
 Post subject: Re: NullPointerException in StatefulPersistenceContext
PostPosted: Thu Aug 11, 2016 9:26 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1589
Location: Romania
Collections should never be declared null.

Try changing this:

Code:
private Set<Child> children;


to this:

Code:
private Set<Child> children = new HashSet<>();

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: NullPointerException in StatefulPersistenceContext
PostPosted: Thu Aug 11, 2016 9:46 am 
Newbie

Joined: Thu Aug 11, 2016 8:56 am
Posts: 3
This:

Code:
private Set<Child> children = new HashSet<>();


Still produces the same error. :(


Top
 Profile  
 
 Post subject: Re: NullPointerException in StatefulPersistenceContext
PostPosted: Thu Aug 11, 2016 11:05 am 
Newbie

Joined: Thu Aug 11, 2016 8:56 am
Posts: 3
I have discovered that if I disable enhancement in pom.xml there is no error.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.