通用Spring Data JPA存储库实现通过类类型加载数据 [英] Generic Spring Data JPA repository implementation to load data by class type
问题描述
我使用Spring Data JPA 1.4.3.RELEASE和Hibernate 4.2.7.Final
我能够成功地创建一个Base Repository类,其行数如下:
http://docs.spring.io/spring-data/jpa/docs/1.4.2.RELEASE/reference/html/repositories.html#repositories.custom-behaviour-for-all-repositories
@NoRepositoryBean
public interface BaseRepository< T扩展了BaseEntity,ID扩展了Serializable>
扩展JpaRepository< T,ID>
@NoRepositoryBean
public class BaseRepositoryImpl< T扩展了BaseEntity,ID扩展了Serializable>
扩展了SimpleJpaRepository< T,ID>实现BaseRepository< T,ID> {
我可以成功处理:
public interface FlowerRepository扩展BaseRepository< Flower,Long> {
现在,我正在尝试编写一个通用实现(扩展基础知识库)像Flower类型的参考数据。
这是因为我不想为每个类型数据或参考数据建立一个存储库。
我希望能够通过传递特定的类类型(实现特定于引用数据类型的接口)来使用通用存储库来管理该类型。例如
loadAll(FlowerType.class)
我使用HBM映射hibernate实体,所以我有:
<?xml version =1.0?>
<!DOCTYPE hibernate-mapping PUBLIC - // Hibernate / Hibernate映射DTD 3.0 // EN
http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd >
< hibernate-mapping>
< class name =xxx.FlowerTypetable =FLWTYP>
< meta attribute =extendsinherit =false> xxx.BaseReferenceType< / meta>
< id name =primaryKeytype =string>
< column name =TYP_CDElength =5/>
< generator class =assigned/>
< / id>
public class FlowerType extends BaseReferenceType< String>实现ReferenceEntity< String>
public abstract class BaseReferenceEntity< T extends Serializable>扩展BaseEntity实现
ReferenceEntity< T>
public abstract class BaseEntity implements DomainEntity
public interface ReferenceEntity< PK extends Serializable> {b $ b
持久性XML:
<?xml version =1.0encoding =UTF-8standalone =no?>
< persistence xmlns =http://java.sun.com/xml/ns/persistence
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance version =2.0
xsi:schemaLocation =http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd >
< persistence-unit name =xxxPU
transaction-type =RESOURCE_LOCAL>
< provider> org.hibernate.ejb.HibernatePersistence< / provider>
< shared-cache-mode> ENABLE_SELECTIVE< / shared-cache-mode>
<属性>
< property name =hibernate.dialectvalue =org.hibernate.dialect.Oracle10gDialect/>
< property name =hibernate.hbm2ddl.autovalue =none/>
< property name =hibernate.ejb.naming_strategyvalue =org.hibernate.cfg.ImprovedNamingStrategy/>
< property name =hibernate.connection.charSetvalue =UTF-8/>
< property name =hibernate.jdbc.batch_sizevalue =100/>
< property name =hibernate.show_sqlvalue =false/>
< property name =hibernate.format_sqlvalue =false/>
< property name =hibernate.transaction.flush_before_completion
value =false/>
< property name =hibernate.connection.autocommitvalue =false/>
< property name =hibernate.ejb.cfgfilevalue =hibernate.cfg.xml/>
< property name =jadira.usertype.autoRegisterUserTypesvalue =true/>
< property name =jadira.usertype.databaseZonevalue =jvm/>
< property name =jadira.usertype.javaZonevalue =jvm/>
< / properties>
< / persistence-unit>
< /余辉>
Hibernate配置:
<?xml version =1.0encoding =UTF-8?>
<!DOCTYPE hibernate-configuration PUBLIC - // Hibernate / Hibernate配置DTD 3.0 // EN
http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd >
< hibernate-configuration>
< session-factory>
< mapping resource =FlowerType.hbm.xml/>
< mapping resource =Flower.hbm.xml/>
< / session-factory>
< / hibernate-configuration>
因此,我查看了一些教程链接和SO帖子,并根据以下内容开展了一些工作:
Spring Jpa将定制功能添加到所有存储库,同时将其他自定义功能添加到单个存储库中
我有:
@NoRepositoryBean
公共接口CustomReferenceDataRepository< T扩展BaseEntity& ReferenceEntity< PK>,PK extends Serializable> {
public map< PK,T> findAll(Class< T> clz);
}
public interface ReferenceDataRepository extends BaseRepository,CustomReferenceDataRepository {
}
public class ReferenceDataRepositoryImpl< T extends BaseEntity& ReferenceEntity< PK>,PK extends Serializable>
实现CustomReferenceDataRepository< T,PK> {
@PersistenceContext
私人EntityManager em;
@覆盖
public Map< PK,T> findAll(Class< T> clz){
//做任何
返回null;
}
}
结束了一个例外:
原因:java.lang.IllegalArgumentException:不是托管类型:class xxx.BaseEntity
位于org.hibernate。 ejb.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:200)〜[hibernate-entitymanager-4.2.7.Final.jar:4.2.7.Final]
at org.springframework.data.jpa.repository.support .JpaMetamodelEntityInformation。< init>(JpaMetamodelEntityInformation.java:68)〜[spring-data-jpa-1.4.3.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport .getMetadata(JpaEntityInformationSupport.java:65)〜[spring-data-jpa-1.4.3.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory。 java:146)〜[spring-data-jpa-1.4.3.RELEASE.jar:na]
我理解Hibernate不管理BaseEntity,但无法弄清楚我缺少什么。
是否需要为参考数据实现通用存储库甚至可能?
如果是,我做错了什么?
任何指导赞赏。
Thanks。
您还必须为BaseEntity添加映射:
< class name =xxx.BaseEntityabstract =true>
您也可以尝试使用注释并设置packagesToScan属性
I am using Spring Data JPA 1.4.3.RELEASE with Hibernate 4.2.7.Final I was able to successfully create a Base Repository class, something on the lines of : http://docs.spring.io/spring-data/jpa/docs/1.4.2.RELEASE/reference/html/repositories.html#repositories.custom-behaviour-for-all-repositories
@NoRepositoryBean
public interface BaseRepository <T extends BaseEntity, ID extends Serializable>
extends JpaRepository<T, ID>
@NoRepositoryBean
public class BaseRepositoryImpl<T extends BaseEntity, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
I am able to sucessfully work with :
public interface FlowerRepository extends BaseRepository<Flower, Long> {
Now, I am trying to write an generic implementation(that extends the base repository) to load all reference data like Flower types. That is because I do not want to have a repository for every single "type" data or "reference" data. I want to be able to manage that using a generic repository by passing a specific "class" type(that implements a interface specific to reference data type).For E-g
loadAll(FlowerType.class)
I use HBMs to map hibernate entities so I have :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="xxx.FlowerType" table="FLWTYP">
<meta attribute="extends" inherit="false">xxx.BaseReferenceType</meta>
<id name="primaryKey" type="string">
<column name="TYP_CDE" length="5" />
<generator class="assigned" />
</id>
public class FlowerType extends BaseReferenceType<String> implements ReferenceEntity<String>
public abstract class BaseReferenceEntity<T extends Serializable> extends BaseEntity implements
ReferenceEntity<T>
public abstract class BaseEntity implements DomainEntity
public interface ReferenceEntity<PK extends Serializable> {
Persistence XML :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="xxxPU"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<property name="hibernate.jdbc.batch_size" value="100" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.transaction.flush_before_completion"
value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
<property name="jadira.usertype.autoRegisterUserTypes" value="true" />
<property name="jadira.usertype.databaseZone" value="jvm" />
<property name="jadira.usertype.javaZone" value="jvm" />
</properties>
</persistence-unit>
</persistence>
Hibernate config :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping resource="FlowerType.hbm.xml"/>
<mapping resource="Flower.hbm.xml"/>
</session-factory>
</hibernate-configuration>
So I looked at some tutorial links and SO posts and did some work based on :
I have :
@NoRepositoryBean
public interface CustomReferenceDataRepository<T extends BaseEntity & ReferenceEntity<PK>, PK extends Serializable> {
public Map<PK, T> findAll(Class<T> clz);
}
public interface ReferenceDataRepository extends BaseRepository, CustomReferenceDataRepository {
}
public class ReferenceDataRepositoryImpl<T extends BaseEntity & ReferenceEntity<PK>, PK extends Serializable>
implements CustomReferenceDataRepository<T, PK> {
@PersistenceContext
private EntityManager em;
@Override
public Map<PK, T> findAll(Class<T> clz) {
//do whatever
return null;
}
}
Ended up with a exception :
Caused by: java.lang.IllegalArgumentException: Not an managed type: class xxx.BaseEntity
at org.hibernate.ejb.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:200) ~[hibernate-entitymanager-4.2.7.Final.jar:4.2.7.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68) ~[spring-data-jpa-1.4.3.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65) ~[spring-data-jpa-1.4.3.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:146) ~[spring-data-jpa-1.4.3.RELEASE.jar:na]
I understand Hibernate does not manage "BaseEntity" but am not able to figure out what I am missing.
Is my requirement of implementing a generic repository for reference data even possible ? If yes, what am I doing wrong ? Any guidance appreciated. Thanks.
You have to add mapping for BaseEntity as well:
<class name="xxx.BaseEntity " abstract="true">
You can also try to use annotations and just set packagesToScan property
这篇关于通用Spring Data JPA存储库实现通过类类型加载数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!