选择继承策略 - 休眠

时间:2017-04-05 00:17:18

标签: java hibernate

如果这个问题在这里得到了解答,我肯定无法找到它,或者它没有特别帮助我。

我已经阅读了一些有关继承映射的教程和一些问题,这些问题无法解决我的问题。

说我有一个抽象类:

  

用户

还有3个其他子类:

  

UserA,UserB,UserC

那些都扩展了用户。

每个子类都有自己的表,超类User,同时,没有。

在我的另一个班级Website我有一个ArrayList,或者我应该说用户的收藏。

该列表应该抓取Website的所有用户。

我应该使用哪种策略?我想到了MappedSuperclass,但是因为在我的Website类中,List是用户类型,所以我不知道该怎么做。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

使用JPA,Java实现总是取决于您自己的偏好和要求,有时这是一个选择的问题。

是的,@ MappedSuperclass会这样做。 您可以让每个孩子都与网站保持单向关系。然后你将在User类中包含Website对象(带有一堆注释),它将作为foreign_key字段映射到数据库(假设你使用SQL存储和来自JPA的'存储库'DAO抽象)。

没有必要在Website类中存储用户集合。试想一下,如果你真的需要它 - 支持一致性可能会很麻烦。 但是有些情况下你需要双向关系。当您将对象存储在内存中时(例如,出于缓存目的),您可能需要拥有此集合。在这种情况下,为什么不拥有'用户'收藏?您将通过专用存储库获取数据(或者即使您没有使用这些数据库,任何其他方式都将使用带有foreign_key的用户表,而不是'网站'表)。

因此,例如,使用Spring Data JPA,您可以在超类中定义单向关系,并在下一个方向使用“存储库”(并且可以在Internet中的任何位置找到双向示例,因此我不提供它):

@Entity
public class SuperUser extends User {   
   ...
}

@Entity
public class BasicUser extends User {   
   ...
}

@MappedSuperclass
public abstract class User implements Serializable {      

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "website_uuid", nullable = false)
    protected Website website;

    ...   
}

@Entity
public class Website implements Serializable {   

   ...
}


@Repository
public interface SuperUserRepository extends CrudRepository<SuperUser, Long> {

   Iterable<SuperUser> findByWebsite(Website website);

}

@Repository
public interface BasicUserRepository extends CrudRepository<BasicUser, Long> {

   Iterable<BasicUser> findByWebsite(Website website);

}

答案 1 :(得分:1)

您要求的似乎是典型的“每个具体的表格式”继承策略。 https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#entity-inheritance-table-per-class

在旧版本的用户指南中,它提到将为每个非抽象类映射单独的表。在最新的文件中,没有提到“非抽象”部分,但我相信它仍然有类似的作用。

所以它看起来像:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class User {...}

@Entity
class UserA extends User {...}

@Entity
class UserB extends User  {...}

@Entity
class UserC extends User  {...}

但是你应该知道这种继承策略通常会在内部使用union时提供低效的查询。