实体类不能转换为java.lang.Number

时间:2014-07-29 16:31:02

标签: java hibernate jpa orm openjpa

此问题是此问题的延续:Foreign key as a part of composite primary key and ManyToOne relationship in OpenJPA

OpenJPA正在将我的实体类(TableB)转换为其键的类型(long)。为什么呢?

在字段TableB中没有任何元素的rows对象的持久工作正常。在向rows添加元素时,问题就开始了。

TableA.class:

package org.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
@IdClass(TableA_PK.class)
public class TableA implements Serializable {
    @Id
    private int fId;
    @Id
    private String item;
    @Id
    private String release;
    @Id
    @ManyToOne
    @JoinColumn(name = "b_id")
    private TableB tableB;
    @Column
    private String field1;
    @Column
    private String field2;

    public TableA() {

    }

    public int getfId() {
        return fId;
    }

    public void setfId(int fId) {
        this.fId = fId;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public String getRelease() {
        return release;
    }

    public void setRelease(String release) {
        this.release = release;
    }

    public TableB getTableB() {
        return tableB;
    }

    public void setTableB(TableB tableB) {
        this.tableB = tableB;
    }

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public String getField2() {
        return field2;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }

}

TableA_PK.class:

package org.model;

import java.io.Serializable;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class TableA_PK implements Serializable {
    private int fId;
    private String item;
    private String release;
    private long tableB;

    public TableA_PK() {
    }

    public int getfId() {
        return fId;
    }

    public void setfId(int fId) {
        this.fId = fId;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public String getRelease() {
        return release;
    }

    public void setRelease(String release) {
        this.release = release;
    }

    public long getTableB() {
        return tableB;
    }

    public void setTableB(long tableB) {
        this.tableB = tableB;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        TableA_PK rhs = (TableA_PK) obj;
        return new EqualsBuilder().append(fId, rhs.fId).append(item, rhs.item)
                .append(release, rhs.release).append(tableB, rhs.tableB)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(fId).append(item).append(release)
                .append(tableB).toHashCode();
    }
}

TableB.class:

package org.model;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
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 org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

@Entity
public class TableB implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column
    private String name;
    @Column
    private Date date;

    @OneToMany(mappedBy = "tableB", cascade = CascadeType.PERSIST)
    private List<TableA> rows;

    public TableB() {
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List<TableA> getRows() {
        return rows;
    }

    public void setRows(List<TableA> rows) {
        this.rows = rows;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        TableB rhs = (TableB) obj;
        return new EqualsBuilder().append(id, rhs.id).append(name, rhs.name)
                .append(date, rhs.date).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(id).append(name).append(date)
                .toHashCode();
    }

}

JpaTest.class:

package org.model;

import java.util.ArrayList;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.junit.Test;

public class JpaTest {

    @Test
    public void test() {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("rd-jpa");
        EntityManager em = entityManagerFactory.createEntityManager();
        EntityTransaction userTransaction = em.getTransaction();
        userTransaction.begin();//BEGIN TRANSACTION 1.
        TableB tableb = new TableB();
        tableb.setDate(new Date());
        tableb.setName("tableb2");
        em.persist(tableb);  // fills tableb id
        userTransaction.commit(); //COMMIT 1
        userTransaction = em.getTransaction();
        userTransaction.begin();//BEGIN TRANSACTION 2.
        TableA tableA = new TableA();
        tableA.setfId(665);
        tableA.setField1("field1");
        tableA.setField2("field2");
        tableA.setItem("item2");
        tableA.setRelease("1");
        tableA.setTableB(tableb);
        ArrayList<TableA> rows = new ArrayList<TableA>();
        rows.add(tableA);
        tableb.setRows(rows);
        em.persist(tableb);
        userTransaction.commit();
        em.clear();
        em.close();
    }
}

运行JpaTest后的堆栈跟踪:

<openjpa-2.3.0-r422266:1540826 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: org.model.TableB cannot be cast to java.lang.Number
    at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2526)
    at org.apache.openjpa.kernel.SingleFieldManager.persist(SingleFieldManager.java:279)
    at org.apache.openjpa.kernel.StateManagerImpl.cascadePersist(StateManagerImpl.java:3081)
    at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2648)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2604)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2587)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2491)
    at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1077)
    at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:716)
    at org.model.JpaTest.test(JpaTest.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number
    at org.apache.openjpa.util.ApplicationIds$PrimaryKeyFieldManager.fetchLongField(ApplicationIds.java:669)
    at org.apache.openjpa.enhance.org$model$TableA$pcsubclass.pcCopyKeyFieldsToObjectId(Unknown Source)
    at org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:169)
    at org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:224)
    at org.apache.openjpa.enhance.ReflectingPersistenceCapable.pcNewObjectIdInstance(ReflectingPersistenceCapable.java:277)
    at org.apache.openjpa.util.ApplicationIds.create(ApplicationIds.java:427)
    at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2675)
    at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2521)
    ... 32 more

的persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<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"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="rd-jpa" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>org.model.TableA</class>
        <class>org.model.TableB</class>
        <properties>
            <property name="openjpa.ConnectionURL"
                value="jdbc:postgresql://localhost:5432/mydb" />
            <property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver" />
            <property name="openjpa.ConnectionUserName" value="postgres" />
            <property name="openjpa.ConnectionPassword" value="postgres" />
            <property name="openjpa.DynamicEnhancementAgent" value="true" />
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
        </properties>
    </persistence-unit>
</persistence>

的pom.xml:

<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>jpa</groupId>
    <artifactId>jpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source />
                    <target />
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa-maven-plugin</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.3-1102-jdbc41</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>
</project>

1 个答案:

答案 0 :(得分:1)

尝试正确删除openjpa.RuntimeUnenhancedClasses属性和enhance您的实体。