我试图坚持一个非常简单的单向一对多关系,但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
具有(并且应该具有)非空约束。
这是一个错误还是代码中有问题?
答案 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]
因此,@JoinColumn
与nullable=true
会导致错误。
另外,您可以使用@OneToMany (..., orphanRemoval = true, ...)
。
答案 5 :(得分:0)
默认情况下,@ JoinColumn上的nullable为true,同时将数据保持一对多关系时,我们需要将nullable设置为false,以避免在运行时发生数据冲突异常。