java - 按类类型加载数据的通用 Spring Data JPA 存储库实现

标签 java spring hibernate spring-data-jpa

我正在使用 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 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> {

我能够成功地工作:

            public interface FlowerRepository extends BaseRepository<Flower, Long> {

现在,我正在尝试编写一个通用实现(扩展基础存储库)来加载所有引用数据,例如 Flower 类型。 那是因为我不想为每个“类型”数据或“引用”数据都建立一个存储库。 我希望能够通过传递特定的“类”类型(实现特定于引用数据类型的接口(interface))来使用通用存储库来管理它。对于 E-g

            loadAll(FlowerType.class)

我使用 HBM 映射 hibernate 实体,所以我有:

            <?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> {

持久性 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 配置:

            <?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 帖子,并根据以下内容做了一些工作:

Spring Jpa adding custom functionality to all repositories and at the same time other custom funcs to a single repository

我有:

            @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;
                }

            }

以异常结束:

            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]

我知道 Hibernate 不管理“BaseEntity”,但我无法弄清楚我错过了什么。

我的要求是否可能实现引用数据的通用存储库? 如果是,我做错了什么? 任何指导表示赞赏。 谢谢。

最佳答案

您还必须为 BaseEntity 添加映射:

<class name="xxx.BaseEntity " abstract="true">

您也可以尝试使用注解并设置 packagesToScan 属性

关于java - 按类类型加载数据的通用 Spring Data JPA 存储库实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21415551/

相关文章:

java - Java中XML节点的计数

java - 在 Spring 中更新属性文件中的数据库设置

hibernate - 如何在 Ubuntu 18.04 中 hibernate

java - 在Android数据库中插入数据时出错

java - android中的主页按钮覆盖

javascript - 如何用Java触发js事件?

使用 spring @Transactional 的 Spring Boot 无需启用事务管理即可工作

java - 找不到 hibernate.cfg.xml (该文件实际上不存在)。配置位于dispatcher-servlet中

java - Spring JPA,CrudRepository 的 save 方法是否立即提交到 DB?

java - 创建文件 [] : Unsatisfied dependency expressed through constructor parameter 1 中定义的名称为 'fieldServiceImpl' 的 bean 时出错