春天 + JPA“超出锁定等待超时;尝试重新启动事务”
我是 Spring 和 JPA 的新手,遇到了标题中指定的问题。为了简化问题,我有两个类:User 和 FeedItem。用户可以拥有更多的 FeedItem,但关系是双向的(FeedItem 知道它与哪个用户关联)。它们都使用 JPA+Hibernate 持久化在数据库中:
@Entity
@Table
public class User
{
@Id
@GeneratedValue
@Column(name = "id", nullable = false, length = 8)
private int id;
@Column(nullable = false, length = 32, unique = true)
private String alias;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<FeedItem> feedItems = new ArrayList<FeedItem>();
public User()
{
}
public User(String alias)
{
this.alias = alias;
}
... getters/setters...
}
@Entity
@Table
public class FeedItem
{
@Id
@GeneratedValue
@Column(name = "id", nullable = false, length = 16)
private int id;
@Column(nullable = false, length = 64)
private String title;
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private User user;
public FeedItem()
{
}
public FeedItem(String title, User user)
{
this.title = title;
this.user = user;
}
... getters/setters...
}
DAO:
@Repository
public class UserJpaDao implements UserDao
{
private EntityManager em;
@Transactional
public User save(User user)
{
return this.em.merge(user);
}
@Transactional
public void delete(User user)
{
this.em.remove(user);
}
@Transactional(readOnly = true)
public User findById(int id)
{
return this.em.find(User.class, id);
}
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
@Repository
public class FeedItemJpaDao implements FeedItemDao
{
private EntityManager em;
@Transactional
public FeedItem save(FeedItem feedItem)
{
return this.em.merge(feedItem);
}
@Transactional
public void delete(FeedItem feedItem)
{
this.em.remove(feedItem);
}
@Transactional
public FeedItem findById(int id)
{
return this.em.find(FeedItem.class, id);
}
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
这是给出错误的测试:
@RunWith(SpringJUnit4ClassRunner.class)
public class FeedItemJpaDaoTest
{
@Autowired
private DriverManagerDataSource dataSource;
@Autowired
private FeedItemJpaDao feedItemDao;
@Autowired
private UserJpaDao userDao;
@Before
@Transactional
public void setUp() throws Exception
{
DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
}
@After
@Transactional
public void tearDown() throws Exception
{
DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet());
}
@Test
@Transactional
public void testSave() throws Exception
{
User user = userDao.findById(3);
FeedItem feedItem = new FeedItem("Achievement unlocked!", user);
feedItem = feedItemDao.save(feedItem);
assertEquals(feedItem, feedItemDao.findById(feedItem.getId()));
}
private IDatabaseConnection getConnection() throws Exception
{
return new DatabaseConnection(dataSource.getConnection());
}
private IDataSet getDataSet() throws Exception
{
return new FlatXmlDataSetBuilder().build(new File("src/test/resources/dataset.xml"));
}
}
我不明白为什么会发生错误 - 任何建议都表示赞赏!
谢谢。
编辑:似乎问题是由于 DbUnit 造成的:如果我注释掉 TeaDown() 方法,则不会发生错误
I'm new to Spring and JPA and I encountered the problem specified in the title. To simplify the problem, I have two classes: User and FeedItem. User can have more FeedItems but the relationship is bi-directional (FeedItem knows with which User it's associated). They're both persisted in the database using JPA+Hibernate:
@Entity
@Table
public class User
{
@Id
@GeneratedValue
@Column(name = "id", nullable = false, length = 8)
private int id;
@Column(nullable = false, length = 32, unique = true)
private String alias;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<FeedItem> feedItems = new ArrayList<FeedItem>();
public User()
{
}
public User(String alias)
{
this.alias = alias;
}
... getters/setters...
}
@Entity
@Table
public class FeedItem
{
@Id
@GeneratedValue
@Column(name = "id", nullable = false, length = 16)
private int id;
@Column(nullable = false, length = 64)
private String title;
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private User user;
public FeedItem()
{
}
public FeedItem(String title, User user)
{
this.title = title;
this.user = user;
}
... getters/setters...
}
The DAOs:
@Repository
public class UserJpaDao implements UserDao
{
private EntityManager em;
@Transactional
public User save(User user)
{
return this.em.merge(user);
}
@Transactional
public void delete(User user)
{
this.em.remove(user);
}
@Transactional(readOnly = true)
public User findById(int id)
{
return this.em.find(User.class, id);
}
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
@Repository
public class FeedItemJpaDao implements FeedItemDao
{
private EntityManager em;
@Transactional
public FeedItem save(FeedItem feedItem)
{
return this.em.merge(feedItem);
}
@Transactional
public void delete(FeedItem feedItem)
{
this.em.remove(feedItem);
}
@Transactional
public FeedItem findById(int id)
{
return this.em.find(FeedItem.class, id);
}
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
This is the test giving the error:
@RunWith(SpringJUnit4ClassRunner.class)
public class FeedItemJpaDaoTest
{
@Autowired
private DriverManagerDataSource dataSource;
@Autowired
private FeedItemJpaDao feedItemDao;
@Autowired
private UserJpaDao userDao;
@Before
@Transactional
public void setUp() throws Exception
{
DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
}
@After
@Transactional
public void tearDown() throws Exception
{
DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet());
}
@Test
@Transactional
public void testSave() throws Exception
{
User user = userDao.findById(3);
FeedItem feedItem = new FeedItem("Achievement unlocked!", user);
feedItem = feedItemDao.save(feedItem);
assertEquals(feedItem, feedItemDao.findById(feedItem.getId()));
}
private IDatabaseConnection getConnection() throws Exception
{
return new DatabaseConnection(dataSource.getConnection());
}
private IDataSet getDataSet() throws Exception
{
return new FlatXmlDataSetBuilder().build(new File("src/test/resources/dataset.xml"));
}
}
I don't understand why the error is happening -- any suggestion is appreciated!
Thank you.
EDIT: Seems like the problem is due to DbUnit: if I comment out the tearDown() method, the error doesn't occour
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决了以下问题: http://tadaya.wordpress.com/2008/04/27/transaction-aware-datasource-use-dbunit-hibernate-in-spring/
Solved the problem following this: http://tadaya.wordpress.com/2008/04/27/transaction-aware-datasource-use-dbunit-hibernate-in-spring/