删除实体违反了字段上的非空约束
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);
我有这个实体
@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);