Java Postgres Hibernate为行级安全设置会话变量

Java Postgres Hibernate为行级安全设置会话变量,java,postgresql,hibernate,Java,Postgresql,Hibernate,我很难找到关于我遇到的这个问题的信息。我对在我的Postgres db上实现行级安全感兴趣,并且我正在寻找一种能够通过某种形式的拦截器自动设置Postgres会话变量的方法。现在,我知道使用hibernate,您可以使用@Filter和@FilterDef执行行级安全性,但是我想在我的数据库上另外设置策略 执行此操作的一个非常简单的方法是在每次查询之前执行SQL语句SET variable=value,尽管我还没有找到有关此操作的任何信息 这是在spring引导应用程序上使用的,每个请求都将访问

我很难找到关于我遇到的这个问题的信息。我对在我的Postgres db上实现行级安全感兴趣,并且我正在寻找一种能够通过某种形式的拦截器自动设置Postgres会话变量的方法。现在,我知道使用hibernate,您可以使用
@Filter
@FilterDef
执行行级安全性,但是我想在我的数据库上另外设置策略

执行此操作的一个非常简单的方法是在每次查询之前执行SQL语句
SET variable=value
,尽管我还没有找到有关此操作的任何信息


这是在spring引导应用程序上使用的,每个请求都将访问
变量的请求特定值

,因为您的应用程序使用spring,所以您可以尝试通过以下几种方法之一来实现这一点:

春季AOP

在这种方法中,您编写了一条建议,要求spring将其应用于特定的方法。如果您的方法使用
@Transactional
注释,则可以在事务启动后立即将建议应用于这些方法

扩展TransactionManager实施

假设您的事务正在使用
JpaTransactionManager

public class SecurityPolicyInjectingJpaTransactionManager extends JpaTransactionManager {
  @Autowired
  private EntityManager entityManager;

  // constructors

  @Override
  protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
    super.prepareSynchronization(status, definition);
    if (status.isNewTransaction()) {
      // Use entityManager to execute your database policy param/values

      // I would suggest you also register an after-completion callback synchronization
      // This after-completion would clear all the policy param/values
      // regardless of whether the transaction succeeded or failed 
      // since this happens just before it gets returned to the connection pool
    }
  }
}
现在只需配置您的JPA环境以使用自定义的
JpaTransactionManager



可能还有其他方法,但我已经探讨过这两种方法。

有几种方法可以实现这一点,但它们都因您可能使用的其他框架而异。告诉我,您的应用程序是使用Spring还是编写为在WildFly这样的应用程序服务器上运行?@Naros该应用程序使用Spring。@NTL您能回答:我今天和明天都会研究这种方法,谢谢。这在很大程度上似乎有效,但我遇到了一个新问题。我已经定义了一个
@Repository
,该
扩展了分页和排序存储库
,并在其中定义了以下签名:
Boolean existemplatebynameignorecase(字符串名)。如果我先调用此函数,则会忽略
SecurityPolicyInjectingJpaTransactionManager
,并且不会执行我在
prepareSynchronization
中的逻辑。更新我以前的注释。通过注释
布尔existemplatebynameignorecase(字符串名),解决了该问题@Transactional
的code>方法。我的问题是,这是否可以在不指定注释的情况下对每个查询执行?传统上,存储库调用由服务方法或控制器方法包装,该方法使用
@Transactional
进行注释。您永远不希望以这种方式注释存储库方法,因为单个原子操作可能涉及多个存储库。例如,要创建订单,我可能需要从
ProductRepository
获取信息,创建订单,然后使用
OrderRepository
保存它。整个操作是单个原子操作,所有操作都应关联到单个数据库事务。