Spring + JPA "Превышено время ожидания блокировки; попробуйте перезапустить транзакцию" - PullRequest
0 голосов
/ 02 февраля 2012

Я новичок в Spring и JPA, и я столкнулся с проблемой, указанной в заголовке.Чтобы упростить задачу, у меня есть два класса: User и FeedItem.Пользователь может иметь больше FeedItems, но связь является двунаправленной (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: если я закомментирую tearDown() метод, ошибка не возникает

1 Ответ

1 голос
/ 09 февраля 2012
...