我正在使用OpenJPA和Eclipse来持久化对象。我创建了一个简单的一对一单向应用程序。但是它给出了外键空值错误。
学生实体
@Entity
public class Student implements Serializable {
@Id
private int id;
private String name;
private static final long serialVersionUID = 1L;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "dept_id", unique = true, nullable = true, insertable = true, updatable = true, referencedColumnName = "id")
private Department department;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public String toString() {
return "\n\nID:" + id + "\nName:" + name + "\n\n" + department;
}
}
部门实体
@Entity
@Table(name = "department")
public class Department implements Serializable {
@Id
private int id;
private String name;
private static final long serialVersionUID = 1L;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String deptName) {
this.name = deptName;
}
public String toString() {
return "Department id: " + getId() + ", name: " + getName();
}
}
的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="IBMJPADemo" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>com.ibm.jpa.onetoone.model.Department</class>
<class>com.ibm.jpa.onetoone.model.Student</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/test" />
<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver" />
<property name="openjpa.ConnectionUserName" value="root" />
<property name="openjpa.ConnectionPassword" value="root" />
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
<!-- property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" /-->
<!-- property name="openjpa.jdbc.MappingDefaults"
value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict" /-->
</properties>
</persistence-unit>
</persistence>
客户计划
public class OneToOneClient {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("IBMJPADemo");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Student student = new Student();
student.setId(2537);
student.setName("K.Senthuran");
Department dept = new Department();
dept.setId(100);
dept.setName("IT");
student.setDepartment(dept);
em.persist(student);
em.flush();
tx.commit();
em.close();
}
}
错误
线程“main”中的异常org.apache.openjpa.persistence.PersistenceException:不允许使用null键 在org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1817) 在org.apache.openjpa.kernel.DelegatingBroker.flush(DelegatingBroker.java:1037) 在org.apache.openjpa.persistence.EntityManagerImpl.flush(EntityManagerImpl.java:652) 在com.ibm.jpa.onetoone.client.OneToOneClient.main(OneToOneClient.java:32) 引起:java.lang.NullPointerException:不允许使用null键 在org.apache.commons.collections.map.AbstractReferenceMap.put(AbstractReferenceMap.java:248) 在org.apache.openjpa.kernel.ManagedCache.assignObjectId(ManagedCache.java:189) 在org.apache.openjpa.kernel.BrokerImpl.assignObjectId(BrokerImpl.java:4949) 在org.apache.openjpa.kernel.BrokerImpl.setStateManager(BrokerImpl.java:4046) at org.apache.openjpa.kernel.StateManagerImpl.assertObjectIdAssigned(StateManagerImpl.java:636) 在org.apache.openjpa.kernel.StateManagerImpl.afterFlush(StateManagerImpl.java:1084) 在org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2162) 在org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2037) 在org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1808) ......还有3个
请帮助解决此问题。
谢谢&amp;问候,
K.Senthuran
答案 0 :(得分:1)
由于您使用的是Uni-Directional
映射,因此保留Student
的{{1}}也不会保留Department
。因此,您需要确保在持久化Student
时,使用的Department
实体引用已经保留在数据库中,否则您将获得异常。
因此,在坚持department
之前,只需坚持student
即可。我认为这将解决您的问题。
如果您愿意,请坚持student
也保留department
,那么您需要使用bi-directional mapping
。即使用Student
中Department
的引用,@OneToOne
映射,指定mappedBy
属性。
答案 1 :(得分:0)
我找到了解决这个问题的方法。
首先,我们必须提到带有@Id和@Column注释的主键属性。
然后我们必须在persistence.xml中添加以下行。
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />