假设我有一个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 的方法,但是我已经放弃了,因为我发现它隐藏了问题并以有害的方式表现-不是不可能掌握,对我个人来说更容易处理。
答案 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();