【发布时间】:2014-02-11 23:32:50
【问题描述】:
JBoss EAP 6
休眠 4
我有一个带有 Web 浏览器客户端的 J2EE 应用程序。 (阿帕奇点击) 内部业务逻辑和客户端都使用相同的实体对象。
我想将实体中的所有关系设置为延迟加载。这样我就有了很好的表现。
但是当使用客户端中的实体(即 apache click 的服务器端代码)时,我需要大量的关系来预先加载。客户端代码通过会话 bean 访问后端。
所以我有两种方法可以解决这个问题:
为每个 JPA 实体创建 2 个,一个用于预加载,一个用于延迟加载。然后在客户端使用预加载的,在服务器中使用延迟加载的。大多数服务器逻辑将在事务中,因此延迟加载在这里很好。
使所有关系延迟加载。从客户端访问实体时,请确保存在事务。 (@TransactionAttribute(TransactionAttributeType.REQUIRED)) 并对必要字段的访问进行编码,以便在会话 bean 调用后可以访问它们。 但这意味着我必须在不需要时启动事务,即如果我只得到一些对象。而且我必须维护更多代码。而且我必须确切地知道客户需要什么关系。
创建一个继承层次结构,其中我有一个超级实体,然后是 2 个子实体,一个具有延迟加载的对象关系,一个只有值,没有对象。即:
超级
@MappedSuperclass
public class SuperOrder {
@Id
@Column(name = "id")
@GeneratedValue(.....)
private Long id;
@Column(name = "invoice", length = 100)
private String invoice;
孩子 1
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "testorder")
@SequenceGenerator(....)
public class Order extends SuperOrder {
@ManyToOne(targetEntity = PrintCustomerEnt.class, fetch = FetchType.EAGER, optional = true)
@JoinColumn(name = "print_customer_id", nullable = true)
@ForeignKey(name = "fk_print_customer")
@Valid
private PrintCustomerEnt printCustomer;
public PrintCustomerEnt getPrintCustomer() {
return printCustomer;
}
public void setPrintCustomer(final PrintCustomerEnt printCustomer) {
this.printCustomer = printCustomer;
}
}
孩子 2
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "testorder")
@SequenceGenerator(...)
public class LazyOrder extends SuperOrder {
@Transient
private String printCustomerName;
@Column(name = "print_customer_id", nullable = true)
private Long printCustomerId;
最佳做法是什么……或者有其他好的方法可以做到这一点。
基本上问题是我想在不同的场景中使用相同的实体。有时我需要预先加载,有时我需要延迟加载。
【问题讨论】:
-
我投给#2。 #1 和 #3 将是未来的大难题
-
我做了类似于你的 #1 和 #3 的事情,它对我来说没问题。不同之处在于,我只是没有较小实体的属性,而不是瞬态或懒惰。所有实体最终都会被转换为模型,因此模型在来自较小实体时将只有一个空值。是的,它变得有点让人头疼,因为它是一个具有许多用例的复杂实体,但它仍然是合理的。我希望 JPA 有一个更好的解决方案,比如 C# 的实体框架......为此,您只需添加 .Include(o => o.printCustomerName) 它将包含它
标签: java hibernate jakarta-ee jpa