У меня есть 2 класса Hibernate в приложении на основе Spring, таких как:
@Entity
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToMany(mappedBy = "picture", fetch = FetchType.LAZY)
private Set<InspectionObjectDetail> inspectionObjectDetails = new HashSet<InspectionObjectDetail>();
@Override
public int hashCode() {
// Eclipse generated hashCode()
}
@Override
public boolean equals(Object obj) {
// Eclipse generated equals()
}
}
и
@Entity
public class InspectionObjectDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToMany (fetch = FetchType.LAZY)
@JoinTable(
name = "MXInspectionObjectDetail_picture",
joinColumns = {@JoinColumn(name = "INSPECTIONOBJECTDETAIL_ID")},
inverseJoinColumns = {@JoinColumn(name = "PICTURE_ID")}
)
@Where(clause = "active = true")
private Set<UOCImage> picture = new HashSet<UOCImage>();
@Override
public int hashCode() {
// Eclipse generated hashCode()
}
@Override
public boolean equals(Object obj) {
// Eclipse generated equals()
}
}
Я могу добавить элементы в это отношение и просто запросить их, ноjUnit-тест, в котором я пытаюсь удалить отношение без фактического удаления одного из этих объектов, завершается неудачей.
В настоящее время я делаю отсоединение каждого объекта от другого в контексте транзакции:
// Junit Test
@Test
public void deleteInspectionObjectDetailImage() {
InspectionObjectDetail inspectionObjectDetail = new InspectionObjectDetail();
dao.save(inspectionObjectDetail);
someClass.saveInspectionObjectDetailImage(controlObject.getId());
//passes
assertTrue(inspectionObjectDetail.getPictures().size() == 1);
UOCImage image = inspectionObjectDetail.getPictures().iterator().next();
someClass.deleteImage(image);
Set<UOCImage> images = inspectionObjectDetail.getPictures();
//fails
assertTrue(images.size() == 0);
}
// BO Class
@Transactional
@Component
public class SomeClass() {
public void delteImage(Image image) {
if(image!= null) {
image.setActive(false);
while(image.getInspectionObjectDetails().iterator().hasNext()) {
InspectionObjectDetail inspectionObjectDetail = image.getInspectionObjectDetails().iterator().next();
inspectionObjectDetail.getPictures().remove(image);
image.getInspectionObjectDetails().remove(inspectionObjectDetail);
}
}
sessionFactory.getCurrentSession().flush();
}
}
Журнал Hibernate сообщает мне, что вставка в отношение к связи выполнена правильно, однако мои операторы удаления выполненыне появляются (даже после сессии.flush ()).Если возможно, я бы хотел продолжать ленивую выборку так, как она есть, потому что я ожидаю много чтений по любой из таблиц, которые не будут загружаться в соответствии с другим загруженным классом.
У кого-то есть указатели для меня?
UPDATE
относительно предложения @ Thor84no, я попытался удалить каждую ассоциацию, удалив ее через функцию iterator.remove()
, поэтому мой объект BO теперь выглядит такthis:
// BO Class
@Transactional
@Component
public class SomeClass() {
public void delteImage(Image image) {
if(image!= null) {
image.setActive(false);
Iterator<InspectionObjectDetail> inspectionObjectDetailsIterator = image.getInspectionObjectDetails().iterator();
while (inspectionObjectDetailsIterator.hasNext()) {
InspectionObjectDetail inspectionObjectDetail = inspectionObjectDetailsIterator.next();
Iterator<UOCImage> imageIterator = inspectionObjectDetail.getPictures().iterator();
while (imageIterator.hasNext()) {
if (imageIterator.next() == image) {
imageIterator.remove();
}
}
inspectionObjectDetailsIterator.remove();
}
}
sessionFactory.getCurrentSession().flush();
}
}
В моем (отредактированном) Junittest:
// ...
someClass.deleteImage(image.getId());
assertTrue(image.getInspectionObjectDetails().size() == 0);
assertTrue(inspectionObjectDetail.getPictures().size() == 0);
Первое утверждение успешно, но второе - неудачно, поэтомудвунаправленная связь между
Image
<-> InspectionObjectDetail
была уменьшена только доImage
<- <code>InspectionObjectDetail