3

我正在尝试使用下表结构在 JPA 中创建 @OneToMany 关系。

+----------------+
| CATALOG        |
+----------------+
| catalogId : PK |
| name           |
+----------------+
      |
+----------------+
| PRODUCT        |
+----------------+
| productId : PK |
| name           |
| catalogId : FK |
+----------------+

我已将类定义为

@Entity
public class Catalog {
    @Id
    @GeneratedValue
    long catalogId;

    @OneToMany(cascade = CascadeType.ALL, 
               orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinColumn(name = "catalogId", 
               nullable = false, insertable = true, updatable = true)
    Set<Product> products = new HashSet<>();

    String name;
}

@Entity
public class Product {
    @Id
    @GeneratedValue
    long productId;

    String name;
}

但是,当我尝试持久化目录对象时,EclipseLink 没有按预期输入 catalogId 值,并且我得到一个 SQL 约束冲突,即存在空值。

另外,我不需要也不需要产品端的@ManyToOne。

持久化代码:

final Catalog catalog = new Catalog();
catalog.name = text;
final Product p = new Product();
p.name = text;
catalog.products.add(p);
em.persist(catalog);

堆栈跟踪:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Column 'CATALOGID'  cannot accept a NULL value.
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1367)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1301)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:866)
    at net.trajano.maven_jee6.ws_mdb_ejb_web.TextMessages.putText(TextMessages.java:61)
4

3 回答 3

7

当您将一个表 Product 上的列的所有权授予不同的实体 Catalog 时,该列将作为持久化 Catalog 的一部分进行更新和维护,而不是作为持久化 Product 的一部分。该框架将创建一个产品,但由于 FK 列由不同的实体“拥有”,因此它将使用目录持久化时生成的单独更新语句来填充该列。您需要使该列可以为空或将该列的所有权放在映射该表的同一实体上。

于 2012-06-15T05:22:57.623 回答
1

我认为这是由于缺少@GeneratedValue注释(带Postgres)。根据我的经验,Postgres您的注释不起作用。您需要指定@SequenceGeneratorand @GeneratedValue。这是一个例子:



    @SequenceGenerator(name = "lan_generator", sequenceName = "lan_pkey_seq")
    @Id
    @GeneratedValue(generator = "lan_generator")
    @Column(name="id", unique=true, nullable=false)
    private Integer id;

如果您正在使用其他数据库,请尝试处理您的数据库。无论如何,在 giveb 链接上,您在使用MySQL. 可能它也适用于您的“内存中德比实例”。

如何使用 JPA 注释注释 MYSQL 自动增量字段

于 2012-06-15T05:27:57.540 回答
0

像这样制作产品类,然后再试一次-

@Entity
public class Product {
    @Id
    @GeneratedValue
    long productId;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "catalogId", updatable = false, insertable = false, nullable=false)  
    private Catalog  catalog ;

    String name;
}
于 2012-06-15T05:19:39.650 回答