我正在创建一个spring boot应用程序,并使用它在JpaRepository
界面中构建来存储我的实体。我有以下两个实体(为了便于阅读,删除了getter和setter):
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(mappedBy = "profileOne", orphanRemoval = true)
private List<Match> matchOnes;
@OneToMany(mappedBy = "profileTwo", orphanRemoval = true)
private List<Match> matchTwos;
}
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames = { "profileOne_id", "profileTwo_id" })
})
public class Match {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
@JoinColumn(name = "profileOne_id")
private Profile profileOne;
@ManyToOne
@JoinColumn(name = "profileTwo_id")
private Profile profileTwo;
}
为了理解JpaRepository
行为,我编写了以下单元测试。
@RunWith(SpringRunner.class)
@DataJpaTest
public class IProfileDaoTest {
@Autowired
private IProfileDao profileDao; //This class extends JpaRepository<Profile, long>
@Autowired
private IMatchDao matchDao; //This class extends JpaRepository<Match, long>
@Test
public void saveProfileTest() throws Exception {
@Test
public void profileMatchRelationTest() throws Exception {
//Test if matches stored by the IMatchDao are retrievable from the IProfileDao
Profile profileOne = new Profile("Bob"),
profileTwo = new Profile("Alex");
profileDao.saveAndFlush(profileOne);
profileDao.saveAndFlush(profileTwo);
matchDao.saveAndFlush(new Match(profileOne, profileTwo));
profileOne = profileDao.getOne(profileOne.getId());
Assert.assertEquals("Match not retrievable by profile.", 1, profileOne.getMatchOnes().size());
}
}
现在我预计匹配会出现在个人资料实体中,但他们没有。我还尝试将CascadeType.ALL
添加到匹配实体中的@ManyToOne
注释,并将FetchType.EAGER
添加到配置文件实体中的@OneToMany
注释。
是否可以通过在profileDao中请求个人资料来获得与matchDao一起保存的匹配?或者我应该找到具有单独功能的配置文件的匹配项?
答案 0 :(得分:1)
Spring Data存储库不会立即写入数据库以获得性能(可能还有其他原因)。在测试中,如果需要测试查询方法,则需要使用@DataJpaTest
提供的TestEntityManager(它只是存储库在后台使用的实体管理器,但有一些方便的测试方法)。 p>
更新1: 匹配项不会添加到配置文件中。为了确保关系是双向的,匹配应该具有配置文件,但配置文件也应该具有匹配。
试试这个:
@RunWith(SpringRunner.class)
@DataJpaTest
public class IProfileDaoTest {
@Autowired
private IProfileDao profileDao; //This class extends JpaRepository<Profile, long>
@Autowired
private IMatchDao matchDao; //This class extends JpaRepository<Match, long>
@Autowired
private TestEntityManager testEntityManager;
@Test
public void saveProfileTest() throws Exception {
@Test
public void profileMatchRelationTest() throws Exception {
//Test if matches stored by the IMatchDao are retrievable from the IProfileDao
Profile profileOne = new Profile("Bob"),
profileTwo = new Profile("Alex");
//Persist the profiles so they exist when they are added to the match
entityManager.persistAndFlush(profileOne);
entityManager.persistAndFlush(profileTwo);
//Create and persist the match with two profiles
Match yourMatch = entityManager.persistFlushFind(new Match(profileOne, profileTwo));
//Add the match to both profiles and persist them again.
profileOne.matchOnes.add(yourMatch);
entityManager.persistAndFlush(profileOne);
profileTwo.matchTwos.add(yourMatch);
entityManager.persistAndFlush(profileTwo);
profileOne = profileDao.getOne(profileOne.getId());
Assert.assertEquals("Match not retrievable by profile.", 1, profileOne.getMatchOnes().size());
}
}
答案 1 :(得分:0)
测试中的所有内容都发生在同一JPA会话中。这样的会话保证每个实体只包含一次。所以当你执行
时profileOne = profileDao.getOne(profileOne.getId());
你正在获得你在上面创建了5行的确切实例。 Hibernate或任何其他JPA实现都将更改实体中的任何内容以进行加载。
如果您想实际重新加载实体,则必须先从实体管理器中逐出,或使用新的Session
/ EntityManager
。
有关详细信息,请参阅JPA规范的第3章。