java 如何为@MappedSuperclass 实现 Spring Data 存储库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27545276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:57:36  来源:igfitidea点击:

How to implement a Spring Data repository for a @MappedSuperclass

javagenericsjpaspring-data

提问by Xtreme Biker

I've got a JPA @MappedSuperClassand an @Entityextending it:

我有一个 JPA@MappedSuperClass和一个@Entity扩展它:

@MappedSuperclass
public class BaseClass {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private Boolean active;

    //getters & setters

}

@Entity
public class Worker extends BaseClass{

    @Column
    private String name;

    //getters & setters

}

The activefield of the base class is a flag for the children entities. Only the active ones should be loaded in the application. Then I've written a generic Spring Data Proxy interface:

active基类的字段是子实体的标志。应仅在应用程序中加载活动的。然后我编写了一个通用的Spring Data Proxy 接口

public interface Dao<T extends BaseClass, E extends Serializable> extends
        CrudRepository<T, E> {

    Iterable<T> findByActive(Boolean active);

}

And this one is the interface that should be for Workerdata access, properly extending the previous one:

而这个应该是Worker数据访问的接口,适当的扩展上一个:

@Transactional
public interface WorkerDao extends Dao<Worker, Long>{}

Well, now in my logic layer I've implemented an abstract class which will wrap the common code for CRUDoperations over my entities. I'll have a service for each of them, but I want just to inherit from the abstractone. I want to wire the specific repository for each of the services and provide it to the superclass using an abstractmethod. That's how my superclass is implemented:

好吧,现在在我的逻辑层中,我已经实现了一个抽象类,它将在我的实体上包装CRUD操作的通用代码。我将为他们每个人提供一项服务,但我只想继承abstract一个服务。我想为每个服务连接特定的存储库,并使用一种abstract方法将其提供给超类。这就是我的超类的实现方式:

public abstract class GenericService<E extends BaseClass>{

    public abstract Dao<E, Long> getDao();

    //Here I've got some common operations for managing 
    //all my application classes, including Worker

}

The problem is that the getDao()method uses the Eclass parameter, which is guaranteed only to be a child of BaseClassand not a javax.persistence.Entity. When I try to access the DAO from my custom service implementation I get this error:

问题在于该getDao()方法使用Eclass 参数,该参数保证仅是 的子项BaseClass而不是javax.persistence.Entity。当我尝试从自定义服务实现访问 DAO 时,出现此错误:

Caused by: java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract java.lang.Iterable com.mycompany.model.daos.interfaces.Dao.findByActive(java.lang.Boolean)! at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:93)

Caused by: java.lang.IllegalArgumentException: Not an entity: class com.mycompany.model.BaseClass at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)

引起:java.lang.IllegalArgumentException:无法为方法公共抽象java.lang.Iterable com.mycompany.model.daos.interfaces.Dao.findByActive(java.lang.Boolean)创建查询元模型!在 org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:93)

引起:java.lang.IllegalArgumentException: Not an entity: class com.mycompany.model.BaseClass at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)

Which makes sense, because Eis defined as a child of BaseClass. The compiler allows me to write this too:

这是有道理的,因为E被定义为BaseClass. 编译器也允许我这样写:

public abstract class GenericService<E extends BaseClass && Entity>

However I get an error in the child Service that says Workerclass is not compatible with the signature for E. Does anybody know how to solve this?

但是,我在子服务中收到错误消息,指出Worker类与E. 有谁知道如何解决这个问题?

回答by Xtreme Biker

It's just a matter of annotating the abstract Repositoryas @NoRepositoryBean:

这只是将摘要注释Repository@NoRepositoryBean

@NoRepositoryBean
public interface Dao<T extends BaseClass, E extends Serializable> extends
        CrudRepository<T, E> {

    Iterable<T> findByActive(Boolean active);

}

This way Spring relies on the underlying repository implementation to execute the findByActivemethod.

这样 Spring 就依赖底层存储库实现来执行该findByActive方法。

Regarding to the annotation type restriction issue, it's not possible to declare an annotation restricted type. See the referenced answers below.

关于注释类型限制问题,无法声明注释限制类型。请参阅下面的参考答案。

See also:

也可以看看: