hibernate - 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);
推荐阅读
- javascript - 在 Vue.js 中加载更多数据时保持相同的垂直坐标
- python - Pandas:条件滚动块计数
- sql-server - 用于提取到 SQL Server 的引用文本限定符
- google-chrome - 使用 chrome 时,使用对象 URL pdf 文件不会从 aws s3 下载。我收到“失败 -Forbidden 错误。适用于 Firefox 和 Edge
- http - 使用邮递员在 D365 F&O 中调用自定义服务
- php - 将订单 ID 与用户 ID 链接并获取用户名 Laravel 7
- reactjs - 需要使用 react hooks 来显示基于按钮的组件
- azure - 访问 Azure SQL 数据库返回不支持的关键字“元数据”错误
- java - 不和谐 Java JDA | 从 SQLite 删除数据/从 SQLite 获取数据
- python - 如果我从寄存器 0x12 读取 6 个字节,BMA490l 将返回零