У меня есть сценарий, похожий на блог, с двумя классами Java: Post и Tag, который является отношением @ManyToMany, с таблицей ассоциаций Post_Tag, вот мои упрощенные определения:
public class Post
{
@ManyToMany(fetch=FetchType.LAZY)
@Fetch(FetchMode.SELECT)
@JoinTable(name = "Post_Tag"
, joinColumns = @JoinColumn(name="Post_id")
, inverseJoinColumns = @JoinColumn(name="Tag_id")
)
private Set<PostTag> tags = new HashSet<PostTag>();
}
public class Tag
{
@ManyToMany(mappedBy="tags" , fetch=FetchType.LAZY)
private Set<Post> comments = new HashSet<Post>();
}
КажетсяХорошо, но в следующем тестовом сценарии это не удается:
- Создать тег, tag1
- Создать 1-е сообщение, post1
- Создать 2-е сообщение, post2
- добавить тег1 к post1.getTags () и post2.getTags ()
- обновить post1, post2
- Список списка = dao.getPostByTag (tag1)
- список утверждений.size () == 2, FAILED
Вот мой тестовый код:
public void testGetCommentsByTag()
{
Tag tag1 = tagDao.save(new Tag("tag1"));
assertTrue(tag1.getId() > 0);
Post post1 = dao.save("...");
Post post2 = dao.save("...");
post1.getTags().add(tag1);
post2.getTags().add(tag1);
dao.update(post1);
dao.update(post2);
List<Post> list = dao.getPostsByTag(tag1 , 0 , 100);
assertSame(2 , list.size()); // FAILED !
assertTrue(list.contains(post1));
assertTrue(list.contains(post2));
}
А вот моя реализация dao.getPostsByTag ():
public List<Post> getPostsByTag(Tag tag , int start, int count)
{
Session session = (Session) em.getDelegate();
Criteria c = session.createCriteria(Post.class);
c.createCriteria("tags")
.add(Restrictions.eq("id", tag.getId()));
c.setFirstResult(start);
c.setMaxResults(count);
c.setCacheable(true);
return c.list();
}
Возвращаемый размер списка == 0!Я заметил сгенерированную команду SQL и обнаружил, что hibernate сначала выполняет getPostsByTag (), а затем вставляет в таблицу ассоциации, что заставляет getPostsByTag () возвращать список 0-длины.:
Hibernate:
insert
into
Tag
values
(?, ?, ?, ?)
Hibernate:
insert
into
Post
(...)
values
(???)
Hibernate:
insert
into
Post
(...)
values
(???)
Hibernate:
select
ooxx
from
Post this_
inner join
Post_Tag tags3_
on this_.id=tags3_.Post_id
inner join
Tag tag1_
on tags3_.Tag_id=tag1_.id
where
and tag1_.id=?
order by
this_.created desc limit ?
Hibernate:
insert
into
Post_Tag
(Post_id, Tag_id)
values
(?, ?)
Hibernate:
insert
into
Post_Tag
(Post_id, Tag_id)
values
(?, ?)
Как убедиться, что getPostsByTag () выполняется after
при вставке таблицы ассоциации?
Я знаю, что были методы 'endTransaction () и startNewTransaction ()'в Spring-JUnit3, но, по-видимому, недоступен в Spring-Junit4.
Но мне интересно, как я могу пройти этот тест в транзакции one
?Спасибо.
среды: Spring4 (SpringJUnit4ClassRunner), hibernate-3.5.6, JPA 2.0