【问题标题】:Access JpaEntityInformation in custom repository implementation在自定义存储库实现中访问 JpaEntityInformation
【发布时间】:2017-10-04 12:10:22
【问题描述】:

我有一些通过片段扩展的Spring Data 存储库,如here 所述。只要我在这个实现中只注入EntityManager,这就可以正常工作。

其中一个实现是通用的,因此需要JpaEntityInformation 的实例才能使当前实体正常工作(我基本上只需要实体名称和 java 类型)。如果我也尝试在构造函数中“自动装配”它,我会得到一个异常,指出找不到 JpaEntityInformation 类的 bean。

我了解此异常,但我想知道是否有其他方法可以获取为其创建当前存储库实例的实体的名称和类。我认为应该可以通过构造函数以某种方式获取JpaEntityInformation,因为如果您指定自定义存储库基类(我不想这样做),这是完成的方式。

您可以在下面找到我刚才描述的用例。

@NoRepositoryBean
@RequiredArgsConstructor
public class FindByFieldRepositoryImpl<T> implements FindByFieldRepository<T> {

    private final JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager manager;

    @Override
    public T findByField(String field, Object value) {
        return createQuery(field, value).getSingleResult();
    }

    private TypedQuery<T> createQuery(String fieldName, Object fieldValue) {
        String entityName = entityInformation.getEntityName();
        Class<T> entityType = entityInformation.getJavaType();

        String queryString = String.format("FROM %s WHERE %s = :value", entityName, fieldName);
        TypedQuery<T> query = manager.createQuery(queryString, entityType);
        return query.setParameter("value", fieldValue);
    }
}

【问题讨论】:

    标签: java spring jpa spring-data-jpa


    【解决方案1】:

    您可以使用JpaEntityInformationSupport 从其类中获取实体信息。您的代码如下所示:

    @NoRepositoryBean
    @RequiredArgsConstructor
    public class FindByFieldRepositoryImpl<T> implements FindByFieldRepository<T> {
    
        private final EntityManager manager;
    
        @Override
        public T findByField(String field, Object value, Class<T> clazz) {
            return createQuery(field, value, clazz).getSingleResult();
        }
    
        private TypedQuery<T> createQuery(String fieldName, Object fieldValue, Class<T> clazz) {
            JpaEntityInformation entityInformation = JpaEntityInformationSupport.getEntityInformation(clazz, manager);
            String entityName = entityInformation.getEntityName();
            Class<T> entityType = entityInformation.getJavaType();
    
            String queryString = String.format("FROM %s WHERE %s = :value", entityName, fieldName);
            TypedQuery<T> query = manager.createQuery(queryString, entityType);
            return query.setParameter("value", fieldValue);
        }
    }
    

    我没有测试过这段代码,但它应该可以工作。

    【讨论】:

    • 这样的问题是,每次调用 findByField 方法都必须提供实体的类,这是多余的信息。所以我不会认为这是一个好的解决方案。但是,我还不确定是否有更好的...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 2017-03-26
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    相关资源
    最近更新 更多