持久化对象时出现“org.apache.openjpa.persistence.PersistenceException:null keys not allowed”错误。

时间:2013-01-22 08:30:56

标签: java jpa-2.0 openjpa

我正在使用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

2 个答案:

答案 0 :(得分:1)

由于您使用的是Uni-Directional映射,因此保留Student的{​​{1}}也不会保留Department。因此,您需要确保在持久化Student时,使用的Department实体引用已经保留在数据库中,否则您将获得异常。

因此,在坚持department之前,只需坚持student即可。我认为这将解决您的问题。

如果您愿意,请坚持student也保留department,那么您需要使用bi-directional mapping。即使用StudentDepartment的引用,@OneToOne映射,指定mappedBy属性。

答案 1 :(得分:0)

我找到了解决这个问题的方法。 首先,我们必须提到带有@Id和@Column注释的主键属性。 然后我们必须在persistence.xml中添加以下行。

<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />