Когда в спящем режиме загружаются сопоставленные отношения - PullRequest
0 голосов
/ 07 мая 2018

Я создаю весеннее загрузочное приложение и использую его встроенный в JpaRepository интерфейс для хранения моих сущностей. У меня есть следующие две сущности (удалены геттеры и сеттеры для удобства чтения):

Профиль лица

@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 в объекте профиля.

Можно ли получить совпадения, сохраненные с matchDao, запросив профиль в profileDao? Или я должен найти совпадения с профилем с отдельной функцией?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Все в вашем тесте происходит в одном сеансе JPA. Такой сеанс гарантирует, что каждый объект включен только один раз. Поэтому, когда вы выполните

profileOne = profileDao.getOne(profileOne.getId());

вы получаете точный экземпляр обратно, вы создали 5 строк выше. Hibernate и любая другая реализация JPA ничего не изменят в сущности для загрузки.

Если вы действительно хотите перезагрузить сущность, вам придется сначала выселить ее из менеджера сущностей или использовать новую Session / EntityManager.

Подробнее см. Главу 3 спецификации JPA.

0 голосов
/ 07 мая 2018

Репозитории Spring Data не записывают в базу данных сразу по причинам производительности (и, возможно, по другим причинам). В тестах, если вам нужно протестировать методы запросов, вам нужно использовать TestEntityManager, предоставленный @DataJpaTest (это просто менеджер сущностей, который репозитории все равно используют в фоновом режиме, но с несколькими удобными методами для тестирования).

Обновление 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());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...