Java 级联型不';不能在内存数据库中工作
我有一个带有数据库的webapp,其中两个实体具有多对多关系,但我手动实现了连接表。当其中一个实体被删除时,它会删除联接表中的所有条目,并更新另一个实体,这样所有实体都可以正常工作,但现在我应该为这个特性编写一个测试。对于我正在使用内存数据库的测试,这是唯一的区别,调用了具有相同注释(和级联类型)的相同方法,但我不断得到:Java 级联型不';不能在内存数据库中工作,java,hibernate,jpa,Java,Hibernate,Jpa,我有一个带有数据库的webapp,其中两个实体具有多对多关系,但我手动实现了连接表。当其中一个实体被删除时,它会删除联接表中的所有条目,并更新另一个实体,这样所有实体都可以正常工作,但现在我应该为这个特性编写一个测试。对于我正在使用内存数据库的测试,这是唯一的区别,调用了具有相同注释(和级联类型)的相同方法,但我不断得到: org.hibernate.exception.ConstraintViolationException: integrity constraint violation: f
org.hibernate.exception.ConstraintViolationException: integrity constraint violation: foreign key no action; FKC17477FD8940DF2B table ENTITY1_ENTITY2
我没有粘贴任何代码,因为我不认为它有任何问题,因为它正在工作。我不要求为我解决这个问题,我只需要知道什么可能导致这种行为,因为我已经没有想法了,我不知道还需要寻找什么。。。谢谢
编辑:以下是一些代码:
@Entity
@Table(name = "interviewer")
public class Interviewer implements Identifiable {
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "interviewer_id")
private Collection<InterviewerTechnology> technologies;
}
@Entity
@Table(name = "technology")
public class Technology implements Identifiable {
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "technology_id")
private Collection<InterviewerTechnology> technologies;
}
@Entity
@Table(name = "interviewer_technology")
public class InterviewerTechnology implements Identifiable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
private Interviewer interviewer;
@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
private Technology technology;
}
@Component
public class TechnologyDao extends AbstractEntityDao<Technology> {
public void remove(Integer id) {
Technology technology = find(id);
em.remove(technology);
}
}
@实体
@表(name=“面试官”)
公开课面试官{
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn(name=“采访者id”)
私人收藏技术;
}
@实体
@表(name=“技术”)
公共类技术实现了可识别的{
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name=“technology\u id”)
私人收藏技术;
}
@实体
@表(name=“面试官\技术”)
公共类技术实现了可识别的{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
@manytone(cascade=CascadeType.MERGE,fetch=FetchType.LAZY)
私人面试官;
@manytone(cascade=CascadeType.MERGE,fetch=FetchType.EAGER)
私有技术;
}
@组成部分
公共类技术DAO扩展了AbstractEntityDao{
公共无效删除(整数id){
技术=查找(id);
em.remove(技术);
}
}
这段代码正是我想要它做的,它只是看起来用于测试的数据库没有看到完成所有工作的级联类型参数我发现了问题,它是
@Transactional
注释。我所有的测试DAO
都在扩展用@Transactional
注释的泛型测试DAO
,我又一次盲目地用它注释了每一个DAO
。这里的问题是,某些操作需要作为单个事务执行(执行后可能需要flush()
),以便数据可以直接用于其他操作。考虑下面的例子:
@Transactional
public abstract class AbstractEntityDao<E> {
@PersistenceContext(unitName = "some-persistence")
protected EntityManager em;
public E create(E e) {
em.persist(e);
return e;
}
(...)
}
@Transactional
公共抽象类AbstractEntityDao{
@PersistenceContext(unitName=“某些持久性”)
受保护的实体管理器em;
公共E创建(E){
em.e;
返回e;
}
(...)
}
这意味着这个类中的每个方法都是一个事务。现在,如果我们用
@Transactional
注释扩展这个类的另一个类,那么每个方法都将是另一个事务,这意味着如果我们在一个方法中删除多个内容,它将需要几个事务(它们都需要调用flush()
方法才能执行级联)但是,它们将作为一个事务运行(除非我们指定传播
)。让这成为每个人(尤其是我)仔细思考哪些操作需要单独的事务,哪些操作可以作为一个事务执行的一个教训。如果您向我们展示代码,对我们来说还是容易得多。好的,将粘贴相关的Piecurestry CascadeType.PERSISTIt与我将其更改为CascadeType.ALL-breaks一样,在应用程序中,仍然无法在testsTurn中使用SQL日志记录并显示发出的语句。但是,如果技术要像一个关系表,那么映射看起来是不正确的。与其在OneToMany上定义联接列,不如指定它由另一端映射。否则,您会告诉JPA,技术和技术之间有两种不同的关系,这可能是导致内存数据库出现问题的原因。