春季 + JPA "Lock wait timeout exceeded; try restarting transaction"



我是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"));
    }
}

我不明白为什么会发生这个错误——任何建议都很感激!

谢谢。

EDIT:问题似乎是由DbUnit引起的:如果我注释掉tearDown()方法,则错误不会出现在中

解决了以下问题:http://tadaya.wordpress.com/2008/04/27/transaction-aware-datasource-use-dbunit-hibernate-in-spring/

最新更新