删除实体违反了字段上的非空约束

Removing entity violates not null constraint on field

我有这个实体

@Entity
class PieceAvailable {

    ...

    @JoinColumn(name = "id_product", referencedColumnName = "id_product")
    @ManyToOne(optional = false)
    private Product idProduct;

    ...

}

我也有 Product 实体,但是它的代码几乎无关紧要(从 Product 到 PieceAvailable 没有关系)。

还有一个密码

PieceAvailable pa = entityManager.find(PieceAvailable.class, 52);
entityManager.remove(pa);

persistence.xml(现在可能没有使用 testPU 持久性单元)

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/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_1_0.xsd">
  <persistence-unit name="crm-ejbPU" transaction-type="JTA">
    <jta-data-source>jdbc/crm</jta-data-source>
    <class>my.company.crm.server.entity.CrmSetting</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>

    </properties>
  </persistence-unit>
  <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>my.company.crm.server.entity.CrmSetting</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
  </persistence-unit>
</persistence>

抛出异常:

Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: null value in column "id_product" violates not-null constraint Detail: Failing row contains (null)(52, null, 2015-08-12 16:05:41.166, 1, 205.33000000000001, null, null, null, null, null, 2015-08-12 16:05:41.166, 0, null). Error Code: 0 Call: UPDATE piece_available SET id_invoice_position_pz = ?, id_piece_available_original = ?, id_product = ?, id_store = ? WHERE (id_piece_available = ?) bind => [5 parameters bound]

我的目标是明确说明删除实体。我不知道为什么eclipselink首先用null填充关系。但它正在发生。这违反了在我的 PostgreSQL 中显然设置的非空约束。在 JPA 中也明确指出,对于此映射,optional = false。所以这是必需的。

如何避免这种异常?我不想删除这个非空约束。

当我为此主题准备最小的示例项目时,我发现我的 PieceAvailable 实体非常不常见。

@Entity
@Table(name = "piece_available")
public class PieceAvailable implements Serializable {

    ...

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_piece_available")
    private Integer idPieceAvailable;

    @JoinColumn(name = "id_product", referencedColumnName = "id_product")
    @ManyToOne(optional = false)
    private Product idProduct;

    @JoinColumn(name = "id_piece_available_original", referencedColumnName = "id_piece_available")
    @ManyToOne(optional = true)
    private PieceAvailable idPieceAvailableOriginal;

    ...
}

PieceAvailable 实体映射到自身的关系(字段 idPieceAvailableOriginal),在我的应用程序中的某些情况下,实体似乎映射到自身。在这些情况下,UPDATE 语句将在删除之前发生。所以当我坚持像这样的实体时:

PieceAvailable pa = new PieceAvailable();
...
pa.setIdPieceAvailableOriginal(pa);

然后在调用 remove 方法后,将上面这样的实体作为参数,我将得到我的异常。

我将不得不修复这个奇怪的关系。但是现在我发现作为解决方法,我可以在删除之前在 idPieceAvailableOriginal 中设置 null 并且我不会得到任何异常。

PieceAvailable pa = entityManager.find(PieceAvailable.class, 52);
pa.setIdPieceAvailableOriginal(null);
entityManager.remove(pa);