java-如何在插入/更新/删除之前使用Hibernate / JPA告诉数据库用户是谁?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-如何在插入/更新/删除之前使用Hibernate / JPA告诉数据库用户是谁?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3463字,纯文字阅读大概需要5分钟。
内容图文
![java-如何在插入/更新/删除之前使用Hibernate / JPA告诉数据库用户是谁?](/upload/InfoBanner/zyjiaocheng/883/785da69db34c4ca8b4a63012fb0a3a2c.jpg)
摘要(详细信息如下):
我想在使用Spring / JPA堆栈保存/更新/删除任何实体之前进行存储的proc调用.
无聊的细节:
我们有一个Oracle / JPA(Hibernate)/ Spring MVC(带有Spring Data repos)应用程序,该应用程序设置为使用触发器将某些表的历史记录到一组历史表中(每个表我们要审核一个历史表).这些实体中的每个实体都具有一个通过在更新或插入时扩展EmptyInterceptor的类设置的modifiedByUser.当触发器归档任何插入或更新时,它可以使用此列轻松查看谁进行了更改(我们对哪个应用程序用户感兴趣,而不是数据库用户感兴趣).问题在于,对于删除,我们不会从执行的SQL中获得最后修改的信息,因为它只是从x到y的纯删除.
为了解决这个问题,我们想执行一个存储过程,以在执行任何操作之前告诉数据库哪个应用程序用户已登录.然后,当发生删除时,审核触发器将查看此值,并使用它记录执行删除操作的人员.
是否有任何方法可以拦截开始事务,或者以其他方式执行SQL或存储过程以告知db,哪些用户正在执行事务中即将发生的插入/更新/删除操作,而其余操作尚未发生?
我希望了解有关数据库方面如何工作的详细信息,但在必要时可以得到更多信息.要点是,存储的proc将创建一个包含会话变量的上下文,并且触发器将在删除时查询该上下文以获取用户ID.
解决方法:
从数据库端开始,这里有一些讨论:
https://docs.oracle.com/cd/B19306_01/network.102/b14266/apdvprxy.htm#i1010372
Many applications use session pooling to set up a number of sessions
to be reused by multiple application users. Users authenticate
themselves to a middle-tier application, which uses a single identity
to log in to the database and maintains all the user connections. In
this model, application users are users who are authenticated to the
middle tier of an application, but who are not known to the
database…..in these situations, the application typically connects
as a single database user and all actions are taken as that user.
Because all user sessions are created as the same user, this security
model makes it very difficult to achieve data separation for each
user. These applications can use the CLIENT_IDENTIFIER attribute to
preserve the real application user identity through to the database.
从Spring / JPA的角度来看,请参阅下面的8.2节:
http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/orcl.connection.html
There are times when you want to prepare the database connection in
certain ways that aren’t easily supported using standard connection
properties. One example would be to set certain session properties in
the SYS_CONTEXT like MODULE or CLIENT_IDENTIFIER. This chapter
explains how to use a ConnectionPreparer to accomplish this. The
example will set the CLIENT_IDENTIFIER.
Spring文档中给出的示例使用XML配置.如果您使用的是Java config,则它看起来像:
@Component
@Aspect
public class ClientIdentifierConnectionPreparer implements ConnectionPreparer
{
@AfterReturning(pointcut = "execution(* *.getConnection(..))", returning = "connection")
public Connection prepare(Connection connection) throws SQLException
{
String webAppUser = //from Spring Security Context or wherever;
CallableStatement cs = connection.prepareCall(
"{ call DBMS_SESSION.SET_IDENTIFIER(?) }");
cs.setString(1, webAppUser);
cs.execute();
cs.close();
return connection;
}
}
通过Configuration类启用AspectJ:
@Configuration
@EnableAspectJAutoProxy
public class SomeConfigurationClass
{
}
请注意,尽管这在Spring的Oracle扩展的特定部分中是隐藏的,但在我看来,第8.2节(与8.1不同)中没有什么是Oracle特定的(除了执行的Statement),并且通用方法应适用于任何通过指定相关的过程调用或SQL即可简单地访问数据库:
以Postgres为例,如下所示,所以我不明白为什么任何使用Postgres的人都不能在下面使用这种方法:
https://www.postgresql.org/docs/8.4/static/sql-set-role.html
内容总结
以上是互联网集市为您收集整理的java-如何在插入/更新/删除之前使用Hibernate / JPA告诉数据库用户是谁?全部内容,希望文章能够帮你解决java-如何在插入/更新/删除之前使用Hibernate / JPA告诉数据库用户是谁?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。