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

Xtr*_*ica 20 java generics jpa spring-data

我有一个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

}
Run Code Online (Sandbox Code Playgroud)

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

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

    Iterable<T> findByActive(Boolean active);

}
Run Code Online (Sandbox Code Playgroud)

这个是应该用于Worker数据访问的接口,正确扩展前一个:

@Transactional
public interface WorkerDao extends Dao<Worker, Long>{}
Run Code Online (Sandbox Code Playgroud)

好吧,现在在我的逻辑层中,我实现了一个抽象类,它将为我的实体包装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

}
Run Code Online (Sandbox Code Playgroud)

问题是该getDao()方法使用了Eclass参数,该参数只保证是一个子节点BaseClass而不是一个子节点javax.persistence.Entity.当我尝试从我的自定义服务实现访问DAO时,我收到此错误:

引起:java.lang.IllegalArgumentException:无法为方法public abstract 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:不是实体:org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)中的com.mycompany.model.BaseClass类

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

public abstract class GenericService<E extends BaseClass && Entity>
Run Code Online (Sandbox Code Playgroud)

但是,我在子服务中收到一个错误,指出Worker类与签名不兼容E.有人知道如何解决这个问题吗?

Xtr*_*ica 25

这只是将摘要注释Repository@NoRepositoryBean:

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

    Iterable<T> findByActive(Boolean active);

}
Run Code Online (Sandbox Code Playgroud)

这样,Spring依赖于底层存储库实现来执行该findByActive方法.

关于注释类型限制问题,不可能声明注释限制类型.请参阅下面的参考答案.

也可以看看: