如何删除@ManyToOne @NotNull引用?

时间:2018-08-08 20:55:08

标签: validation jpa many-to-one

假设我有一个e

// Test.h
extern int externalint;  // just declares externalint

// Test.cpp
int externalint = 10;  // defines externalint

// main.cpp
#include "Test.h"  // importing the declaration of "externalint" defined elsewhere
int main() {
  std::cout << externalint << std::endl;  
}

引用Entity0

@Entity
public class Entity0 implements Serializable {
    @Id
    private Long id;
    @ManyToOne
    @NotNull
    private Entity1 entity1;

    public Entity0() {
    }

    public Entity0(Long id,
            Entity1 entity1) {
        this.id = id;
        this.entity1 = entity1;
    }

    [getter and setter for id and entity1]
}

Entity1注释对于断言在@Entity public class Entity1 implements Serializable { @Id private Long id; @Basic private String property0; public Entity1() { } public Entity1(Long id, String property0) { this.id = id; this.property0 = property0; } [getter and setter for id and property0] } @NotNull期间设置Entity0.entity1很有用。但是,它不允许删除对persist的引用(将其设置为merge并将实例合并到持久性上下文中),这对于删除所引用的Entity1实例是必需的。我想知道是否完全可以在实体中拥有null属性。以下内容说明了由于我采用各种方法而使从持久性中删除Entity1实例成为可能的问题:

@ManyToOne @NotNull

代码包含这么多Entity1,因为我是在JTA环境中重现此代码的,在JTA环境中,事务的各个部分之间可能发生刷新。

我知道我可以删除EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("de.richtercloud_jpa-not-nulll-many-to-one-removal_jar_1.0-SNAPSHOTPU"); EntityManager entityManager = entityManagerFactory.createEntityManager(); Entity1 entity1 = new Entity1(2l, "abc"); Entity0 entity0 = new Entity0(1l, entity1); entityManager.getTransaction().begin(); entityManager.persist(entity1); entityManager.persist(entity0); entityManager.flush(); entityManager.getTransaction().commit(); entityManager.close(); entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); entity1 = entityManager.merge(entity1); entity0 = entityManager.merge(entity0); //1: fails due to `ERROR 23503: DELETE on table 'ENTITY1' caused a violation of foreign key constraint 'FK5CQRG47R3H3KQG834IH36DUB' for key (2). The statement has been rolled back.` //entityManager.remove(entity1); //entityManager.flush(); //entityManager.merge(entity0); //entityManager.flush(); //2: entity0.setEntity1(null); entityManager.remove(entity1); entityManager.flush(); entityManager.merge(entity0); entityManager.flush(); entityManager.getTransaction().commit(); entityManager.close(); entityManagerFactory.close(); 注释来解决此问题。我的问题是,是否有任何解决方案可以同时具有注释和删除功能。如果不可能,是否将引用临时设置为伪造的flush实例还是放弃@NotNull呢?

级联可能是一种有效的方法,即使不是 the 的方法,但是我已经放弃了,因为我发现它隐藏了问题并以有害的方式表现-不是不可能掌握,对我个人来说更容易处理。

2 个答案:

答案 0 :(得分:0)

如果是级联的一种方式,则可以将以下内容添加到您的实体1

@OneToMany(cascade=CascadeType.REMOVE) 
private List<Entity0> entity0s;

这样,当删除entity1时,引用的entity0将被删除。 级联可能很危险,因此始终删除引用的实体是否是个好主意,您应该三思而行。有时最好先删除引用,然后再删除“父”实体。

答案 1 :(得分:0)

我不确定我是什么问题,为什么您认为必须在@NotNull外键声明上设置@ManyToOne@NotNull不是JPA批注。如果要将数据库列设置为非null,则应使用:

@ManyToOne
@JoinColumn(name = "entity1_id", nullable=false)
private Entity1 entity1;

因此,如果您想拥有nullable=false并将它们都删除,请先删除孩子,然后再删除父母。

tx.begin();
entity1 = em.find(Entity1.class, 1L);
entity0 = em.find(Entity0.class, 2L);
em.remove(entity0);
em.remove(entity1);
tx.commit();