gpt4 book ai didi

java - 如何避免使用 MOXy 加载惰性双向关系?

转载 作者:行者123 更新时间:2023-11-30 03:26:07 31 4
gpt4 key购买 nike

我的问题是 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 方法在 Phone 上运行查询(使用底层 EJB):

@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 查询,我可以使用相同的单个 SELECT 语句获取关联的 Employee

当 JAX-RS 方法返回时,JAXB 编码启动,这会导致额外的 SQL SELECT:此选择选择其 employeeID 指向的所有 Phone与最初请求的电话关联的Employee。因此,从 EmployeePhone 的惰性关系现在已经解决,大概是因为 MOXy 必须能够确定原始 Phone 是否包含在集合中.

我已尝试按照其他线程中的建议对 phones 字段使用 JPA 属性访问和 JAXB 字段访问,但无济于事。我还尝试在从 EJB 检索结果后(即当我的实体已分离时)将链接的 Employee 实例中的 Phones 字段清空,但这导致了再次立即执行 SQL SELECT(似乎只要对 IndirectList 进行任何操作,EclipseLink 就会执行此操作?)。我能找到的唯一解决方案是将 MOXy @XmlNamedObjectGraph 与排除 phones 字段的子图一起使用。但这是不切实际的,特别是当涉及的实体具有许多属性时。

因为我可能也需要向另一个方向查询,例如员工的姓名及其关联的电话,我不能只将电话标记为@XmlTransient

有人有一个优雅的解决方案来抑制这些额外的 SQL 语句吗?

最佳答案

根据我的经验,完成您尝试的操作的最简单方法是在将所有实体类传递到 JAX-RS Rest api 等表示层之前分离它们。您甚至可以使用@OneToMany(mappedBy = "employee", cascade = CascadeType.DETACH)EntityManager.detach()分离您的电话类别,然后分离您的员工类别,反之亦然。这将确保在编码实体期间,Jax-RS 不会触发您通常不需要的任何 SELECT 语句。

我总是在将模型实体传递到表示层之前分离它们,以便它们可以按照自己的意愿与模型类交互,而不会影响性能或数据库。

关于java - 如何避免使用 MOXy 加载惰性双向关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30163294/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com