我正在尝试进行以下交易:
- 创建一个客户端
- 创建一个带有外键的地址到客户端表
- 将客户端的组合外键更新到地址表
问题:
- 运行 testMethod() 时,我得到一个 关于 ADDRESSES 约束的java.sql.SQLIntegrityConstraintViolationException
- 如果我在一个事务中更改代码并创建客户端,然后在另一个事务中创建地址并更新客户端字段,一切正常
- 如果我更改代码并在一个事务中创建客户端和地址并在另一事务中更新客户端字段,一切正常
如果我使用本地查询而不是 EntityManager 中的持久和合并方法,一切正常
@Stateless public class Test implements TestLocal { @PersistenceContext(unitName = "testPU") private EntityManager em; @Override public void testMethod(Client client, Address address, boolean mainAddress) { client.setIdcliente(new Long(110)); em.persist(client); address.setAddressPK(new AddressPK(new Long(120), client.getIdcliente())); em.persist(address); if (mainAddress) { client.setMainAddress(address); em.merge(client); } }
我的模型:
客户:
- IDCLIENTE pk
- NMORADAPRI 可为空
外键 (IDCLIENTE, NMORADAPRI) 参考地址 (IDCLIENTE, IDMORADA)
@Entity
@Table(name = "CLIENTS")
public class Client implements Serializable {
@Id
@Basic(optional = false)
@NotNull
@Column(name = "IDCLIENTE")
private Long idcliente;
@JoinColumns({
@JoinColumn(name = "IDCLIENTE", referencedColumnName = "IDCLIENTE", insertable = false, updatable = false),
@JoinColumn(name = "NMORADAPRI", referencedColumnName = "IDMORADA")})
@OneToOne(optional = false)
private Address main_address;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "client")
private Collection<Address> addressesCollection;
地址:
- IDMORADA pk
- IDCLIENTE pk
外键 (IDCLIENTE) 参考客户 (IDCLIENTE)
@Entity
@Table(name = "ADDRESSES")
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected AddressPK addressPK;
@JoinColumn(name = "IDCLIENTE", referencedColumnName = "IDCLIENTE", insertable = false, updatable = false)
@ManyToOne(optional = false)
private Client client;
组合键
@Embeddable
public class AddressPK implements Serializable {
@Basic(optional = false)
@NotNull
@Column(name = "IDMORADA")
private long idmorada;
@Basic(optional = false)
@NotNull
@Column(name = "IDCLIENTE")
private long idcliente;