【发布时间】:2015-05-11 08:53:03
【问题描述】:
我的问题是对this 评论的跟进。
我在同一个类中混合了 JPA 和 JAXB (MOXy) 注释,这在大多数情况下都可以正常工作。如链接线程中所述,@XmlInverseReference 在编组双向关系时防止循环异常。但是为了检测循环,MOXy 必须检查链接实体的反向引用,如果需要填充惰性关系,这会导致额外的 SQL SELECT。
为了详细说明问题,请考虑这个虚构的示例:
@Entity
@Access( AccessType.FIELD )
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD )
public class Phone {
@ManyToOne
@JoinColumn( name = "employeeID" )
@XmlElement( name = "employee" )
@XmlInverseReference( mappedBy = "phones" )
private Employee employee;
private String number;
[...]
}
@Entity
@Access( AccessType.FIELD )
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD )
public class Employee {
@OneToMany( mappedBy = "employee" )
@XmlElementWrapper( name = "phones" )
@XmlElement( name = "phone" )
@XmlInverseReference( mappedBy = "employee" )
private List<Phone> phones;
private String name;
[...]
}
现在我将使用这样的 JAX-RS 方法(使用底层 EJB)在 Phones 上运行查询:
@Inject
private PhoneService phoneService;
@GET
@Path( "/phones" )
public List<Phone> getPhonesByNumber( @QueryParam( "number" ) String number ) {
List<Phone> result = phoneService.getPhonesByNumber( number );
return result;
}
发生的情况是这样的:PhoneService EJB 中的 JPQL 查询触发了Phone 表上的 SQL SELECT(按数字过滤),如果我使用 JOIN FETCH 查询,我可以获得关联的 @ 987654329@ 使用相同的单个 SELECT 语句。
当 JAX-RS 方法返回时,JAXB 编组启动,这会导致额外的 SQL SELECT:这个选择所有 Phones,其 employeeID 指向与最初请求的 Employee 关联Phones。所以Employee到Phone的惰性关系现在就解决了,大概是因为MOXy必须能够判断原来的Phone是否包含在集合中。
按照其他线程中的建议,我尝试对 phones 字段使用 JPA 属性访问和 JAXB 字段访问,但无济于事。在从 EJB 检索结果后,我还尝试将链接的 Employee 实例中的 phones 字段清空,即当我的实体已经分离时,但这会导致再次立即执行 SQL SELECT(似乎 EclipseLink 会每当对 IndirectList?) 进行任何操作时都执行此操作。我能找到的唯一解决方法是将 MOXy @XmlNamedObjectGraphs 与排除 phones 字段的子图一起使用。但这不切实际,尤其是在涉及的实体有很多属性的情况下。
因为我也可能需要向另一个方向查询,例如员工的姓名及其相关电话,我不能只将phones 标记为@XmlTransient。
有没有人有一个优雅的解决方案来抑制这些额外的 SQL 语句?
【问题讨论】:
标签: java jpa jaxb eclipselink moxy