保留实体时的额外选择

时间:2019-05-26 06:33:22

标签: hibernate jpa

当我尝试保存实体时

@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 :(得分:0)

在这个阶段,这不仅仅是一个讨论,而不是一个答案,但是对于代码示例,则需要更多的注释...

快速测试,将new Role(existingRoleId)分配给ProfileRole很好,没有对role表进行额外选择。

额外的选择可能指向保存或合并role的内容。选择Hibernate之后,便找不到需要更新回数据库的更改。

跟踪@PostLoad上的Role方法是跟踪角色选择内容的直接方法。例如,它可以转储当前堆栈跟踪:

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

如果运气好的话,这将带来领先优势。

答案 1 :(得分:0)

通常,为避免在创建具有多对一关联实体的实体时避免过多选择,您应该获取它们的引用。

因此,在您的情况下,应获取ProfileRole的引用(如果您还没有),然后使用它们创建ProfileRoles,例如:

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

更多信息:How do find and getReference EntityManager methods work when using JPA and Hibernate