gpt4 book ai didi

java - java中如何设计JPA多态关系?

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

我正在设计产品目录。我想要一棵类别树,其中产品只能连接到LeafCategories,它可以有一个父类别。我正在使用 Spring Boot、Spring Data 和 Hibernate 4 以及 H2 数据库(目前)。

任务的基础实体是AbstractCategory(是否有更好的方法来继承关系?)(省略了Getters和Setters,NamedEntity是一个带有字符串名称的@MappedSuperclass和长 ID)

public abstract class AbstractCategory extends NamedEntity{
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "parentId")
Category parent;
}

类别实体 - 它们不是叶子,不能将产品连接到它们:

@Entity
public class Category extends AbstractCategory {

@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
Collection<AbstractCategory> subcategories;
}

LeafCategory它可以用作我的Product实体的属性。

@Entity
public class LeafCategory extends AbstractCategory {
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "category")
Collection<Product> products;
}

我有一个非常简单的 CrudRepository 用于 Category 和一个相同的 LeafCategory

@Repository
@Transactional
public interface CategoryRepository extends CrudRepository<Category, Long> {}

当我从 CategoryRepository 加载类别并访问 getSubcategories() 时,出现以下异常:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: uj.jg.domain.products.Category.subcategories,  could not initialize proxy - no Session

首先 - 我怎样才能改进设计?第二个也是更具体的问题是为什么 @Transactional 不保持 session 打开?我知道我可以只使用 FetchType.EAGER,但它是一个递归结构 - 如果我对 Hibernate 的理解是正确的,那么这意味着加载整个子树,而我不希望这样。我也不想使用 Hibernate.initialize

我没有任何数据库或 hibernate 配置。我正在使用 spring.boot 中的开发工具:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

最佳答案

How can I improve the design?

我觉得这很合理。

Why is @Transactional not keeping a session open?

您已将 @Transactional 放置在存储库中。数据库 session 仅在运行查询时打开,该查询返回类别及其子类别标记为延迟加载的类别。然后, session 关闭(一旦存储库方法返回),并且当不再有 session 时,您将尝试访问子类别。如果您使用的是 3 层架构,则将 @Transactional 注释移至调用堆栈的较高位置 - 移至服务层(参见 this post )。

由于存储库方法仅运行单个查询,因此无需将它们标记为@Transactional - 它们无论如何都会在事务中运行。仅当您运行多个查询或运行查询和其他一些处理(这可能会引发异常并且您希望因此回滚查询)时,使用 @Transactional 才有意义。这就是为什么,如果您想将任何内容显式标记为 @Transactional,它宁愿在服务层中。

关于java - java中如何设计JPA多态关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35226891/

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