当我在非拥有方(User)上添加@OneToOne映射时,我在执行查询时会额外选择加载Staff。一旦我删除了用户类中的@OneToOne,就解决了N + 1问题。
User.staff设置为lazy,因此不应该尝试加载它。
我缺少什么,或双向关联总是如此?
/* named HQL query Staff.findByName */
/* load com.xxx.Staff */
/* load com.xxx.Staff */
/* load com.xxx.Staff */
PS。用户不一定是工作人员,但工作人员必须是用户。
员工班级
@Entity
@Table(name = "staff")
@NamedQueries({
@NamedQuery(name = Staff.QUERY_BY_NAME, query = "from Staff s left join fetch s.user u left join fetch u.staff where (lower(s.user.displayName) like :key) or (lower(s.user.lastName) like :key)")})
public class Staff extends AbstractDomainObject<Long> {
public static final String QUERY_BY_NAME = "Staff.findByName";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
用户类
@Entity
@Table(name = "env_user")
@SecondaryTable(name = "app_user")
public class User extends AbstractUserDetailsDomainObject<Long> {
public static final String QUERY_BY_USERNAME = "User.findByUsername";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = true, fetch = FetchType.LAZY, mappedBy = "user")
private Staff staff;
}
答案 0 :(得分:0)
感谢Alan Hay提供解决方案的链接。我选择的最干净的解决方案是使用FieldHandled。 @OneToMany破坏了逻辑结构,仪器的东西很容易被未来的开发人员遗忘和遗忘。
public class User extends AbstractUserDetailsDomainObject<Long> implements FieldHandled {
public static final String QUERY_BY_USERNAME = "User.findByUsername";
/**
* <p>
* Required to allow lazy loading of Staff @OneToOne association
* </p>
*/
private FieldHandler fieldHandler;
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, optional = true)
@LazyToOne(LazyToOneOption.NO_PROXY)
private Staff staff;
/**
* <p>
* Staff Getter
* </p>
* Uses fieldhandler to force lazy loading
*
* @return the staff
*/
public Staff getStaff() {
Staff result = this.staff;
if (this.fieldHandler != null) {
result = (Staff) this.fieldHandler.readObject(this, "staff", this.staff);
}
return result;
}
/**
* <p>
* Staff Setter
* </p>
* Uses fieldhandler to force lazy loading
*
* @param staff
* the staff to set
*/
public void setStaff(final Staff staff) {
if (this.fieldHandler != null) {
this.staff = (Staff) this.fieldHandler.writeObject(this, "staff", this.staff, staff);
} else {
this.staff = staff;
}
}
/**
* <p>
* FieldHandled interface method.
* </p>
* Required to allow lazy loading of Staff @OneToOne association
*/
public FieldHandler getFieldHandler() {
return this.fieldHandler;
}
/**
* <p>
* FieldHandled interface method.
* </p>
* Required to allow lazy loading of Staff @OneToOne association
*/
public void setFieldHandler(final FieldHandler fieldHandler) {
this.fieldHandler = fieldHandler;
}
}