Дополнительный выбор при сохранении сущности - PullRequest
0 голосов
/ 26 мая 2019

Когда я пытаюсь сохранить сущность

@Autowired
private GenericDao<ProfileRoles, Integer> gProfileRolesDao;
...
gProfileRolesDao.create(new ProfileRoles(new Profile(idProfile), new Role(role)));

С create

@Repository
public class GenericDao<T, PK extends Serializable>  {

    @PersistenceContext
    private EntityManager entityManager;
    ...
    public T create(T t) {
        this.entityManager.persist(t);
        return t;
    }

И ProfileRoles сущностью

@Entity
@Table(name="profile_roles")
public class ProfileRoles {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "profile")
    private Profile profile;

    @ManyToOne
    @JoinColumn(name = "role")
    private Role role;

Все хорошо, ноя получаю дополнительный выбор

Hibernate: select role_.id, role_.label as label2_22_ from role role_ where role_.id=?
Hibernate: insert into profile_roles (profile, role) values (?, ?)

Как я могу оптимизировать это?

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

В общем, чтобы избежать лишних выборов при создании сущности, которая имеет много-к-одному связанных сущностей, сначала вы должны получить ссылки на них.

Так что в вашем случае вы должны взять ссылки на Profile и Role (если у вас их еще нет), а затем создайте ProfileRoles с ними, например:

// begin transaction
Profile profile = entityManager.getReference(Profile.class, profileId);
Role role = entityManager.getReference(Role.class, roleId);
entityManager.persist(new ProfileRoles(profile, role))
// commit

Дополнительная информация: Как найти и получить методы EntityManager GetReferenceработать при использовании JPA и Hibernate

0 голосов
/ 28 мая 2019

На данном этапе это скорее обсуждение, чем ответ, но для примера кода нужно больше, чем комментарий ...

Быстрый тест, присвоение new Role(existingRoleId) для ProfileRole работало нормально, без дополнительного выбора для таблицы role.

Дополнительный выбор может указывать на сохранение или объединение role. После выбора Hibernate не находит изменений, которые необходимо обновить обратно в базу данных.

Простой способ отследить то, что выбирается для роли, - это @PostLoad метод на Role. Например, он может сбросить текущую трассировку стека:

@PostLoad
public void postLoad() {
    new Exception("Post-load trace stack").printStackTrace();
}

Если повезет, это обеспечит преимущество.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...