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

时间:2014-12-18 11:15:27

标签: 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

}

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

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

    Iterable<T> findByActive(Boolean active);

}

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

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

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

}

问题在于getDao()方法使用E类参数,该参数仅保证为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:不是实体:class com.mycompany.model.BaseClass       在org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)

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

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

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

1 个答案:

答案 0 :(得分:20)

只需将摘要Repository注释为@NoRepositoryBean

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

    Iterable<T> findByActive(Boolean active);

}

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

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

另见: