我有一个单向相关实体:
dfc = dict()
mydict = {1: 6, 2: 4,3: 10, 4: 7, 5: 3}
for i, (k, v) in enumerate(mydict.items()):
dfc[(i)] = v
print("index: {}, key: {}, value: {}".format(i, k, v))
for i in range(0,5,1):
result[i] = dfc[i] * dfc[i+1]
以及以下测试:
File "<ipython-input-139-b31501e8f8af>", line 2, in <module>
result[i] = dfc[i] * dfc[i+1]
KeyError: 5
@Entity
public class Book {
private String isbn;
}
@Entity
private class Recommentation {
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "book_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private Book book;
}
在不是从测试中调用此代码时效果很好,但是在测试中我得到例外,即书未删除推荐。
此外,我尝试从SQL记录以获取有关休眠查询的任何信息,但此测试我看不到任何@RunWith(SpringRunner.class)
@DataJpaTest
public class BookRepositoryTest {
@Autowired
private TestEntityManager testEntityManager;
@Autowired
private BookRepository bookRepository;
@Test
public void delete() {
// given
String isbn = "isbn-1";
Book book = new Book();
book.setIsbn(isbn);
testEntityManager.persist(book);
Recommendation recommendation = new Recommendation();
recommendation.setBook(book);
testEntityManager.persist(recommendation);
// when
bookRepository.deleteBookByIsbn(book.getIsbn());
// then
assertThat(testEntityManager.find(Book.class, book.getId())).isNull();
assertThat(testEntityManager.find(Recommendation.class, recommendation.getId())).isNull();
}
}
语句。
我不想为实体使用双向链接,而只是想了解如何解决这个具体问题或以某种方式对其进行调试。
答案 0 :(得分:2)
需要注意的几点:
首先,据我所知@OnDelete(action = OnDeleteAction.CASCADE)
仅影响DDL的生成,即FK是使用on delete cascade
子句在数据库中创建的。然后,您将级联删除操作委派给数据库,如果您没有让Hibernate生成架构,则此注释将无效。由于将级联删除委托给数据库,您将看不到Hibernate正在执行的任何SQL删除语句。
第二,在测试中,您正在使用JPQL查询删除实体:
bookRepository.deleteBookByIsbn(book.getIsbn());
而不是使用entityManager.remove(e)
(通过存储库的delete(e)
方法)。
其结果是,即使您将JPA CacadeType.DELETE
应用于关联,由于批量JPQL更新/删除查询也不会自动执行,因此删除操作不会级联。< / p>
在此处进一步了解这一点:
答案 1 :(得分:1)
@ManyToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "book_id", nullable = false)
private Book book;
编辑1:
@ManyToOne(optional = false)
@JoinColumn(name = "book_id",
nullable = false,
foreignKey = @ForeignKey(
foreignKeyDefinition = "FOREIGN KEY (book_id) REFERENCES book(id) ON DELETE CASCADE"
)
)
private Book book;
如果您不希望进行双向映射,而模式是由实体创建的,则以下方法可以解决问题。
如果您通过SQL创建架构,则也可以在脚本中创建这样的外键。
这种方法还希望仅执行一个删除查询。