Hibernate:添加强制谓词



我们在应用程序中引入了一些角色,基于这个角色,用户必须访问过滤后的数据。我们已经构建了一个服务,根据用户角色返回必须添加到请求中的谓词。

是否可以以强制和自动的方式将谓词添加到Hibernate将推送到数据库的每个请求中?或者是否存在另一种方式来提供";强制过滤";休眠请求?

首先要考虑的是:尝试覆盖实体管理器以添加此行为。

谢谢。

这是不可能的,因为用例是非常特殊的IMO。很少所有表都有一组相等的列,可以为其应用谓词。

您可以尝试用一个自定义实现来覆盖org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl#statementPreparer,但我不认为这样的谓词适用于您正在执行的所有SQL。

我不知道这个谓词是什么样子的,但你研究过Hibernate中的多租户支持吗?如果您只需要某种tenant = 123谓词,那么使用Hibernate就很容易了。如果您需要更多,您将不得不以某种方式将此谓词添加到您使用的每个查询中。在JPQL/HQL或标准中。

如果谓词的语法类似于JPQL/HQL,则可以使用Blaze Persistence,它是一个查询生成器,接受支持任意深度路径表达式的扩展JPQL变体。这可能看起来像下面的

CriteriaBuilder<Cat> criteriaBuilder = criteriaBuilderFactory.create(entityManager, Cat.class, "cat");
criteriaBuilder.whereExpression("abc > 0 and def = 123"); // Your predicate

如果谓词在不同的抽象级别上,则需要对持久性级别进行某种转换。这就是Blaze Expression可以帮助您的地方,它是一个开发自定义DSL的工具包,可以序列化到Blaze Persistence查询生成器上。

CriteriaBuilder<Cat> criteriaBuilder = criteriaBuilderFactory.create(entityManager, Cat.class, "cat");
// Parse predicate against your context
ExpressionServiceFactory expressionServiceFactory = Expressions.forModel(domain);
ExpressionCompiler compiler = expressionServiceFactory.createCompiler();
ExpressionCompiler.Context context = compiler.createContext(
Collections.singletonMap("c", domain.getType("CatModel"))
);
Predicate predicate = compiler.createPredicate("abc > 0 and def = 123", context);
// Apply predicate onto the query builder
ExpressionSerializer<WhereBuilder> serializer = expressionServiceFactory.createSerializer(WhereBuilder.class);
ExpressionSerializer.Context context = serializer.createContext(
Collections.singletonMap("c", "cat")
);
serializer.serializeTo(context, predicate, criteriaBuilder);

最新更新