Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 作为复合主键一部分的外键和OpenJPA中的多通关系_Java_Hibernate_Jpa_Orm_Openjpa - Fatal编程技术网

Java 作为复合主键一部分的外键和OpenJPA中的多通关系

Java 作为复合主键一部分的外键和OpenJPA中的多通关系,java,hibernate,jpa,orm,openjpa,Java,Hibernate,Jpa,Orm,Openjpa,我想用OpenJPA2.3创建简单的数据库 TableA: - f_id PK - item PK - release PK - b_id PK - field1 - field2 TableB: - id PK - name - date 其中TableA中的b_id引用了TableB中的id(多个TableA行到一个TableB行)b_id是整个复合主键的一部分 表格A类: @Entity @IdClass(TableA_PK.class) public c

我想用OpenJPA2.3创建简单的数据库

TableA:
- f_id    PK
- item    PK
- release PK
- b_id    PK
- field1
- field2

TableB:
- id      PK
- name
- date
其中
TableA
中的
b_id
引用了
TableB
中的
id
(多个
TableA
行到一个
TableB
行)
b_id
是整个复合主键的一部分

表格A类:

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

    public TableA() {}
    //getters, setters, equals, hashCode methods
}
public class TableA_PK implements Serializable {
    private int fId;
    private String item;
    private String release;
    private TableB tableB;

    public TableA_PK() {}
    //getters, setters, equals, hashCode methods
}
 @Entity 
 public class TableB implements Serializable {
    @Id
    @GeneratedValue
    private long id;
    @Column
    private String name;
    @Column
    private Date date;

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

    public TableB() {}
    //getters, setters, equals, hashCode methods
}
表A主键类:

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

    public TableA() {}
    //getters, setters, equals, hashCode methods
}
public class TableA_PK implements Serializable {
    private int fId;
    private String item;
    private String release;
    private TableB tableB;

    public TableA_PK() {}
    //getters, setters, equals, hashCode methods
}
 @Entity 
 public class TableB implements Serializable {
    @Id
    @GeneratedValue
    private long id;
    @Column
    private String name;
    @Column
    private Date date;

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

    public TableB() {}
    //getters, setters, equals, hashCode methods
}
表格B类别:

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

    public TableA() {}
    //getters, setters, equals, hashCode methods
}
public class TableA_PK implements Serializable {
    private int fId;
    private String item;
    private String release;
    private TableB tableB;

    public TableA_PK() {}
    //getters, setters, equals, hashCode methods
}
 @Entity 
 public class TableB implements Serializable {
    @Id
    @GeneratedValue
    private long id;
    @Column
    private String name;
    @Column
    private Date date;

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

    public TableB() {}
    //getters, setters, equals, hashCode methods
}
如何解决这个问题

我的理论/解释:看起来,当我试图持久化
TableB
对象时,
行的每个元素都必须持久化。但是在
TableA
中有一个字段
private TableB TableB
(它还没有持久化),所以我们陷入无限递归;)

编辑:

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

    public TableA() {}
    //getters, setters, equals, hashCode methods
}
public class TableA_PK implements Serializable {
    private int fId;
    private String item;
    private String release;
    private TableB tableB;

    public TableA_PK() {}
    //getters, setters, equals, hashCode methods
}
 @Entity 
 public class TableB implements Serializable {
    @Id
    @GeneratedValue
    private long id;
    @Column
    private String name;
    @Column
    private Date date;

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

    public TableB() {}
    //getters, setters, equals, hashCode methods
}
完整跟踪(更改前):

更改后的完整跟踪(当我更改
table a_PK
table b
Long
类型,以及
table b
id
Long
类型时):

我有例外:

org.apache.openjpa.persistence.RollbackException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
(...)
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ERROR: null value in column "b_id" violates not-null constraint
为什么??我认为它将首先保持
tb
,然后
行中的每个元素都将知道获得的TableB.id(感谢
TableA
类中的
TableB
字段)。这个怎么了

如果在持久化之前在测试中添加两行:

ta1.setTableB(tb);
ta2.setTableB(tb);
将抛出此异常:

Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number
(我需要自己在
TableA
中设置
tableB
字段吗?)

如何持久化
TableB
对象

编辑3: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>

org.apache.openjpa.persistence.PersistenceProviderImpl
org.model.TableA
org.model.TableB

这对我来说适用于以下代码。更改了TableA_PK中的长tableB和TableA中的@join列

@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;
表a_PK

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

    public TableA_PK() {}
    //getters, setters, equals, hashCode methods
表B

@Entity 
public class TableB implements Serializable {
   @Id
   @GeneratedValue
   private long id;
   @Column
   private String name;
   @Column
   private Date date;

   @OneToMany(mappedBy="tableB")
   private List<TableA> rows;

   public TableB() {}
   //getters, setters, equals, hashCode methods
@实体
公共类TableB实现了可序列化{
@身份证
@生成值
私人长id;
@纵队
私有字符串名称;
@纵队
私人日期;
@OneToMany(mappedBy=“表B”)
私有列表行;
公共表B(){}
//getter、setter、equals、hashCode方法
评论后更新
不幸的是,派生键不支持生成的值,并且在插入项之前不知道该值。因此,您需要先持久化tableB项,然后添加行。 检查以下代码:

    TableB tableb = new TableB();
    tableb.setDate(new Date());
    tableb.setName("tableb2");
    em.persist(tableb);  // fills tableb id
    System.out.println(tableb); 
    TableA tableA = new TableA();
    tableA.setfId((int) new Date().getTime());
    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.merge(tableb);  // inserts tablea objects, you could also just persist tableA items
TableB TableB=新TableB();
表B.设置日期(新日期());
表B.集合名称(“表B2”);
em.persist(tableb);//填充tableb id
系统输出打印项次(表B);
TableA TableA=新TableA();
tableA.setfId((int)new Date().getTime());
表A.设置字段1(“字段1”);
表A.设置字段2(“字段2”);
表A.设定项目(“项目2”);
表A.设定释放(“1”);
表A.设置表B(表B);
ArrayList行=新的ArrayList();
行。添加(表a);
表B.设置行(行);
em.merge(tableb);//插入tablea对象,也可以只保留tablea项

我相信在TableA_PK中,而不是“TableB TableB”,你只需要TableB中的一个主键,而不是整个实体-“private long TableB;”我明天在工作时会检查这个:)你能告诉我这到底应该是什么样子吗?在
TableA_PK中
我需要将
private TableB TableB
更改为
private long id
>就这样?关于
TableA
?不需要更改吗?检查JPA2.0规范中的2.4.1.3派生标识示例。key类中的属性应该与@Id中使用的属性名称匹配,因此它是tableB而不是Id,并且type应该与tableB的主键类型匹配,在您的情况下,这就是为什么我建议使用
private-long tableB
。如果它不起作用,我们将寻找其他东西;-)。现在没有时间测试它。TableA中没有变化。它不起作用,@Gas。我添加了完整的异常痕迹,谢谢。但我可能正在“填充”
TableA
TableB
的字段以错误的方式显示对象。请查看我的第二篇postscript,谢谢您的帮助,但它不起作用。我创建实体类和测试类与上述完全相同,我仍然有
原因:java.lang.ClassCastException:org.model.TableB无法转换为java.lang.Number
。我添加了my
persistence.xml
文件。我正在考虑重新组织我的数据库架构。这一问题的完整堆栈跟踪是什么:由:java.lang.ClassCastException引起的?为了可读性,我添加了一个新问题:所有源代码