我认为这是一个奇怪的问题,但它确实存在!
放入上下文: 我正在实现我的JUnit测试,我正在测试一个名为songJPA的类。我创建了一首歌(OK),然后我创建了一个同名的歌曲,我期待一个异常(OK),最后我想删除第一首歌创建(在下一个执行测试时间没有错误)。
问题在于,当我单独执行DeleteSongTest()时,它会工作并删除我的歌曲,但是当我执行所有这些时,它不起作用,它进入无限递归。我认为它发生在flush()方法中,我试图调试,但这是不可能的。
我粘贴了所有正在工作的课程。
JUNIT TEST CLASS:
public class SongCRUDTest {
private SongJPA testSong1;
private SongJPA testSong2;
private SongJPAJpaController slc;
@Before
public void setUp() {
testSong1= new SongJPA("TestTitle", 120, 19, new SongInfoJPA(), "TestArtist", Genre.CLASSICAL);
testSong2= new SongJPA("TestTitle", 122, 12, new SongInfoJPA(), "TestArtist2", Genre.BLUES);
slc = new SongJPAJpaController();
}
@Test
public void A_createSong(){
slc.create(testSong1);
}
@Test(expected = PersistenceException.class)
public void B_createDuplicatedTestSong() {
slc.create(testSong2);
}
@Ignore
@Test
public void C_deleteSong() throws NonexistentEntityException{
SongJPA songToDelete= slc.findSongJPAByTitle("TestTitle");
if(songToDelete!=null)
slc.destroy(songToDelete.getId());
}
仅在我单独执行时才有效的destroy方法。 (来自netbeans模板)
public void destroy(int id) throws NonexistentEntityException {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
SongJPA songJPA;
try {
songJPA = em.getReference(SongJPA.class, id);
songJPA.getId();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The songJPA with id " + id + " no longer exists.", enfe);
}
em.remove(songJPA);
em.flush();
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
EDITION1:create()方法
public void create(SongJPA songJPA) {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
em.persist(songJPA);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
秒后
54587 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL错误:1205,SQLState:41000 54587 [main] ERROR org.hibernate.util.JDBCExceptionReporter - 超出锁定等待超时;试试>重启交易
TIA寻求帮助!!!!
答案 0 :(得分:2)
从JPA方法获得异常后,必须考虑必须回滚事务,并且必须关闭EM:第一级缓存处于错误状态且无法恢复。有关详细信息,请参阅http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/#transactions-demarcation-exceptions。
使用EM.find
而不是EM.getReference
,并测试null。当您知道具有给定ID的实体时,将使用getReference
。因此,如果它稍后出现它会引发异常,但它已经太晚了。而find
执行查询以获取实体的状态,而如果它不存在则返回null。如果实体尚不存在,您可以创建该实体,如果存在,则删除它。
此外,您似乎期望测试按固定顺序运行。你不应该。每个单元测试应该单独运行,并且应该运行是否已经运行了先前的测试。使用注释为@After
的方法在每次测试后执行一些清理。