JPA - 使用EclipseLink保持单向一对多关系失败

时间:2012-10-05 23:39:47

标签: java jpa orm eclipselink

我试图坚持一个非常简单的单向一对多关系,但EclipseLink(2.3.1)失败。

服务类(父母):

@Entity
@Table(name = "tbl_service2")
public class Service implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="service_id")
    public long serviceID;

    @Column(name="name")
    public String name;

    @OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="service_id", referencedColumnName="service_id")
    public Set<Parameter> parameters;
}

参数类(Child):
(当然在数据库中有“service_id”外键字段,它没有在类中表示,因为它是单向关系)。

@Entity
@Table(name = "tbl_service_parameters2")
public class Parameter implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="param_id")
    public long parameterID;

    @Column(name="name")
    public String name;
}

这是实体持久性的代码:

    Service service = new Service();
    service.parameters = new HashSet<Parameter>();
    service.name = "test";
    Parameter param = new Parameter();
    param.name = "test";
    service.parameters.add(param);
    em.persist(service);
    em.flush();

我得到了这个例外:

Internal Exception: java.sql.SQLException: Field 'service_id' doesn't have a default value
Error Code: 1364
Call: INSERT INTO tbl_service_parameters2 (name) VALUES (?)
    bind => [test]

编辑:由于数据的性质,数据库字段service_id具有(并且应该具有)非空约束。

这是一个错误还是代码中有问题?

6 个答案:

答案 0 :(得分:29)

使用nullable = false上的@JoinColumn

@JoinColumn(name = "service_id", nullable = false)

答案 1 :(得分:14)

尝试删除Parameter表的service_id字段中的not null约束。 Eclipselink将在单独的语句中更新单向1:m连接列的外键,因此您需要禁用或延迟约束检查。将其设置为双向将允许使用其余参数数据更新fp字段。

答案 2 :(得分:1)

您可以更改hibernate版本&lt; 4.0的持久性,并且您的代码将运行良好。“参考”中的“井”仅用于一对多关系保存/持久父级,不通过单独的任务保存/保存子级的收集“< / p>

答案 3 :(得分:1)

通过使用可延迟的外键,我能够在Oracle中使用它。

示例:

ALTER TABLE my_table ADD CONSTRAINT my_constraint_name FOREIGN KEY (my_table_column) REFERENCES foreign_key_table  (foreign_key_table_column) DEFERRABLE INITIALLY DEFERRED

答案 4 :(得分:0)

正如我发现的那样,在这种情况下,外键填写在单独的声明中。在我的示例中,我使用Address实体和customer_id作为外键。

2014-07-08T20:51:12.752+0300|FINE: INSERT INTO ADDRESS (address_id, street, city, region) VALUES (?, ?, ?, ?)
    bind => [10, foo, foo, foo]
2014-07-08T20:51:12.753+0300|FINEST: Execute query InsertObjectQuery(ua.test.customer.Address@28cef39d)
2014-07-08T20:51:12.757+0300|FINEST: Execute query DataModifyQuery(sql="UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?)")
2014-07-08T20:51:12.757+0300|FINE: UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?)
    bind => [151, 10]

因此,@JoinColumnnullable=true会导致错误。

另外,您可以使用@OneToMany (..., orphanRemoval = true, ...)

答案 5 :(得分:0)

默认情况下,@ JoinColumn上的nullable为true,同时将数据保持一对多关系时,我们需要将nullable设置为false,以避免在运行时发生数据冲突异常。