Я новичок в 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() метод, ошибка не возникает