繁体   English   中英

具有Inheritance.JOINED的Spring数据存储库

[英]Spring Data Repository with Inheritance.JOINED

我在应用程序中设计了实体,使其遵循Hibernate的继承策略Inheritance.JOINED

基本抽象类是UserTable ,具体派生类是ClientTableOwnerTable

我要实现的事情是拥有一个单一的存储库,在该存储库中,我可以通过IdEmail find任何UserTableClientTableOwnerTable )。 重要的要求是,一旦获取它们就可以将其强制转换为正确的类型,并且它们必须携带其特定的字段(而不仅仅是从UserTable继承的字段)。

同样重要的是,我应该能够通过相同的存储库来持久化那些实体。 repository.save(clientTable)

所以这样的事情应该是可能的:

UserTableRepository repository = // ...

int clientId = 3; 
int ownerId = 5;

ClientTable clientTable = (ClientTable) repository.findByUserId(clientId);
OwnerTable clientTable = (OwnerTable) repository.findByUserId(ownerId);

clientTable = (ClientTable) repository.findByEmail(clientEmail);
ownerTable = (OwnerTable) repository.findByEmail(ownerEmail);

我的实体看起来像这样。

UserTable.java

@Entity
@Table(name = "USER")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class UserTable implements Serializable {

    @Column(name = "USER_ID", nullable = false)
    private Long userId;

    @EmbeddedId
    private UserTablePK userTablePK;

    @Column(name = "PASSWORD", nullable = false, length = 512)
    private String password;

    @Column(name = "FIRSTNAME", nullable = false, length = 256)
    private String firstName;

    // get, set
}

..和主键

UserTablePK.java

@Embeddable
public class UserTablePK implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "EMAIL", nullable = false, length = 256)
    private String email;

    public UserTablePK() {
    }

    public UserTablePK(String email) {
        this.email = email;
    }

    // get, set
}

ClientTable.java

@Entity
@Table(name = "CLIENT")
public class ClientTable extends UserTable implements Serializable {

    @Column(name = "SHOPING_POWER")
    private Integer shoppingPower;

    @Column(name = "SHOPPING_FREQUENCY")
    private Integer shoppingFreq;

    // get, set
}

OwnerTable.java

@Entity
@Table(name = "OWNER")
public class OwnerTable extends UserTable implements Serializable {

    @Column(name = "EFFICIENCY")
    private String efficiency;

    @Column(name = "SALARAY")
    private Integer;

    // get, set
}

现在设置了实体之后,我需要编写一个类似于上述操作的存储库,在这里我需要一些帮助。 我当时想写这样的东西。

UserTableRepository.java

@Repository
public interface UserTableRepository extends CrudRepository<UserTable, UserTablePK> {

    @Query("SELECT e FROM UserTable e WHERE e.userTablePK.email = ?1")
    public UserTable findByEmail(String email); // if owner email, retrieve OwnerTable; if client email, retrieve ClientTable instance

    @Query("SELECT e FROM UserTable e WHERE e.userId = ?1")
    public UserTable findByUserId(Long userId); // if owner id, retrieve OwnerTable; if client id, retrieve ClientTable instance
}

我实际上还没有尝试过,因为我想检查这是否是正确的方法,但是:我相当怀疑此Query是否有效。 因为要检索整个子类对象,应使用某种JOIN,而问题是我无法明确地说出ie。 JOIN ClientTable因为那样我将无法获取任何OwnerTable实体。

如何实现可以从同一个存储库中获取两个子类?

UPDATE

同样,要求是能够获取特定的子类。 所以像这样:

List<ClientTable> clients = repository.findAllClients();

是否可以使用相同的存储库,还是应该编写特定于子类的存储库? 例如。

@Repository
public interface ClientTableRepository extends CrudRepository<ClientTable, ClientTablePK> {
 // empty
}

...然后像这样称呼他们:

ClientTableRepository repository = // ...

List<ClientTable> clients = repository.findAll();

JPA是否足以确定如何查找特定子类的所有实例是否足够?

您想要实现的正是JPA中继承的工作方式。

因此,您的查询非常好,结果列表中将包含子类的实例。

在我的一篇博客文章中了解有关JPA继承的更多信息:

https://martinelli.ch/2018/01/04/inheritance-in-jpa/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM