我有all_objects
实体:
Academy
@Entity
@Table(name = "academy")
public class Academy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String address;
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "parent")
private List<Institute> institutes;
public Academy() {}
public Academy(String name, String address, List<Institute> institutes) {
this.name = name;
this.address = address;
this.institutes = institutes;
}
实体:
Institute
这个想法是@Entity
@Table(name = "institute")
public class Institute {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column(name = "building_code")
private String buildingCode;
@ManyToOne(optional = false)
private Academy parent;
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "parent")
private List<Department> departments;
public Institute() {}
public Institute(String name, String buildingCode, Academy parent, List<Department> departments) {
this.name = name;
this.buildingCode = buildingCode;
this.parent = parent;
this.departments = departments;
parent.getInstitutes().add(this);
}
是父,Academy
是孩子(树状结构)。 Institute
有Institute
个 - 但此刻并不重要。删除Department
时,我正在使用orphanRemoval = true
删除所有Academy
个孩子(机构等...):
Academy
当我使用应用程序时,一切似乎都没问题 - 当我删除UnitServiceImpl.java
与此@Override
@Transactional
public String remove(String whatIsRemoved, Long id) {
if (whatIsRemoved.equals("academy")){
Academy academy = getAcademyById(id);
academy.getInstitutes().clear();
getCurrentSession().delete(academy);
}
else if (whatIsRemoved.equals("institute")){
Institute institute = getInstituteById(id);
institute.getParent().getInstitutes().remove(institute);
}
//other if's etc..
}
及其Academy
等相关的每个Institute
时..从数据库中删除(我正在使用Academy
)。简而言之 - 它表现为树状结构。但是,如果我尝试使用内存数据库编写单元测试(我在Department
版本中使用PostgreSQL 9.3
),这应该证明:
hsqldb
与&#34; Michigan&#34;相关的Instututes仍然在&#34;密歇根州&#34;作为父母和测试崩溃。这意味着我错了,在2.3.2
数据库中也没有删除它们(但我检查它并且@Test
@Transactional
public void test_WhenAcademyWasRemoved_InstitutesAlsoShouldBeRemoved() throws Exception {
UnitServiceImpl service = new UnitServiceImpl();
service.setSessionFactory(sessionFactory);
AcademyDTO michigan = new AcademyDTO(null, "Michigan", "test");
service.saveAcademy(michigan);
service.saveInstitute(new InstituteDTO(null, "IT", "D", getAcademyIdByName(service, "Michigan"), null));
service.remove("academy", getAcademyIdByName(service, "Michigan"));
List<Institute> institutes = (List<Institute>)sessionFactory.getCurrentSession().createCriteria(Institute.class).list();
assertEquals(0, institutes.size());
}
是空的)?或者,它只表示在PostgreSQL
提交时将删除它们?因为测试方法需要Instututes
,没有它测试不会编译 - 但是,如何测试它?我被卡住了,因为在应用程序中它看起来不错,但在使用内存数据库的单元测试中,它不能正常工作,因为我认为它应该。如果有人帮助我,我会很高兴 - 提前谢谢你。
更新:问题是:Transaction
适用于localhost数据库,在我看来是因为提交了事务,然后应用了级联删除。如何在单元测试中以非常复杂的方式执行相同的操作 - 比如在测试结束之前提交事务(触发级联删除),然后用另一个@Transactional
获取orphanRemoval = true
s?我在测试中尝试了私有Institute
方法,但它无法正常工作。
答案 0 :(得分:2)
我认为问题可能是测试中的事务处理方式与“普通”代码中的处理方式不同(这会让我自己一次又一次地困惑)。
让我们确认我理解你的问题是正确的:
使用mysql数据库运行应用程序时一切正常。
但是当您针对hsqldb级联运行测试时,删除似乎失败了。
我认为两种情况之间的区别在于事务处理,更重要的是将更改从会话刷新到数据库的时间,即sql语句实际执行。
要验证这一点,您可以激活sql日志记录,以查看您的数据何时存储在数据库中。我的期望是,在生产中,这最早发生在每个@Transactional方法结束时,但是在测试中,由于测试中的@Transactional注释并且没有发生冲洗,或者至少不是同一个,所以一切都在单个事务中运行时间点。
为了模拟生产行为,您可以在通常交易结束的地方添加对Session.flush
的调用。
答案 1 :(得分:1)
请注意,春天AOP不会削减@Transactional的私人方法。尝试将测试实用程序方法公开,然后再次调用。希望它有效!