简体   繁体   English

访问自定义存储库实现中的JpaEntityInformation

[英]Access JpaEntityInformation in custom repository implementation

I have some Spring Data repositories that are extended via fragments as described here . 我有一些Spring Data存储库,通过这里描述的片段进行扩展。 This works fine as long as I only inject the EntityManager in this implementations. 只要我在这个实现中只注入EntityManager ,这就可以正常工作。

One of those implementations is generic and therefor needs an instance of JpaEntityInformation for the current entity to work correctly (I basically only need the entity name and java type). 其中一个实现是通用的,因此需要一个JpaEntityInformation实例,以使当前实体正常工作(我基本上只需要实体名称和java类型)。 If I try to "autowire" this in the constructor as well, I get an exception that says that no bean of class JpaEntityInformation could be found. 如果我尝试在构造函数中“自动”这个,我得到一个异常,说明找不到类JpaEntityInformation bean。

I understand this exception but I'd like to know whether there is another way to get name and class of the entity the current repository instance was created for. 我理解这个异常,但我想知道是否有另一种方法来获取为当前存储库实例创建的实体的名称和类。 I thought that it should be possible to somehow get the JpaEntityInformation via the constructor because this is the way it is done if you specify a custom repository base class (which I don't want to do). 我认为应该可以通过构造函数以某种方式获取JpaEntityInformation ,因为如果您指定自定义存储库基类(我不想这样做),这就是它的完成方式。

Below you can find a use case for what I just described. 下面你可以找到我刚才描述的用例。

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

You can use JpaEntityInformationSupport to get entity information from its class. 您可以使用JpaEntityInformationSupport从其类中获取实体信息。 Here's how your code would look like: 以下是您的代码的外观:

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

I haven't tested this code but it should work. 我没有测试过这段代码,但它应该可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM