如何为@MappedSuperclass实现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接口 :
public interface Dao extends CrudRepository { Iterable findByActive(Boolean active); }
这个应该是Worker
数据访问的接口,正确扩展前一个:
@Transactional public interface WorkerDao extends Dao{}
好吧,现在在我的逻辑层中,我实现了一个抽象类,它将为我的实体包装CRUD操作的公共代码。 我将为他们每个人提供服务,但我只想inheritanceabstract
。 我想为每个服务连接特定的存储库,并使用abstract
方法将其提供给超类。 这就是我的超类的实现方式:
public abstract class GenericService{ public abstract Dao 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:不是实体:org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)中的com.mycompany.model.BaseClass类
这是有道理的,因为E
被定义为BaseClass
的子级。 编译器允许我写这个:
public abstract class GenericService
但是,我在子服务中收到错误,指出Worker
类与E
的签名不兼容。 有谁知道如何解决这个问题?
这只是将抽象Repository
注释为@NoRepositoryBean
:
@NoRepositoryBean public interface Dao extends CrudRepository { Iterable findByActive(Boolean active); }
这样,Spring依赖底层存储库实现来执行findByActive
方法。
关于注释类型限制问题, 不可能声明注释限制类型 。 请参阅下面的参考答案。
也可以看看:
- 通用Spring Data JPA存储库实现,用于按类类型加载数据
- 注释:限制对带注释的类的引用