I have seen various reports of NPE problems in CollectionBinder.bindCollectionSecondPass() but no clear solution and usually with the response of "give an example that fails". OK, here is a simple set of files that causes the following stack trace. Any help appreciated... this is killing my current project...
Hibernate jar files:
hibernate-core-4.3.5.Final.jar
hibernate-commons-annotations-4.0.4.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
Code:
Caused by: java.lang.NullPointerException
at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1456)
at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:864)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:779)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:728)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at com.test.ServletEventListener.buildSessionFactory(ServletEventListener.java:61)
at com.test.ServletEventListener.contextInitialized(ServletEventListener.java:27)
Person entity class (removing the phoneList OneToMany relationship avoids the NPE):
UPDATE: Just removing the @JoinColumn also avoids the NPE.
Code:
package com.cabintechglobal.pdir.model;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonManagedReference;
@Entity
@Table(name="PERSON")
public class Person {
//----- Columns
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(nullable=false, unique=true)
private int personId;
@Column(nullable=false, length=50)
private String firstName;
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(referencedColumnName="phoneId") // Column in PHONE table
private Set<Phone> phoneList;
//---- Getters/Setters
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Set<Phone> getPhoneList() {
return phoneList;
}
public void setPhoneList(Set<Phone> phoneList) {
this.phoneList = phoneList;
}
}
The other side of the relationship:
Code:
package com.cabintechglobal.pdir.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="PHONE")
public class Phone {
//----- Columns
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(nullable=false, unique=true)
private int phoneId;
@Column(nullable=true, length=10)
private String number;
@Column(nullable=true, length=10)
private String extension;
@Column(nullable=true, length=15)
private String type;
//---- Getters/Setters
public int getPhoneId() {
return phoneId;
}
public void setPhoneId(int phoneId) {
this.phoneId = phoneId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Hibernate configuration:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
<property name="connection.url">jdbc:derby:Databases/TestDB;create=true</property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.DerbyDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<!--property name="connection.pool_size">1</property-->
<!-- Echo all executed SQL to stdout -->
<!--property name="show_sql">true</property-->
<!-- Create/update the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.test.TestUser"></mapping>
<mapping class="com.cabintechglobal.pdir.model.Person"></mapping>
<mapping class="com.cabintechglobal.pdir.model.StaffDetail"></mapping>
<mapping class="com.cabintechglobal.pdir.model.Phone"></mapping>
</session-factory>
</hibernate-configuration>
Initialization Java code:
Code:
// Create the SessionFactory from hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate Annotation Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Annotation serviceRegistry created");
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;