JPA可以方法进行注释

标准用例--您需要一个器,以便在每次更新/插入/删除时执行一些代码。例如,用于审计。但是,如果您需要侦听器中的Spring依赖,并且您正在使用JPA,那么事情就不那么简单了。

首先,只有侦不够的JPA可以用@PreUpdate对方法进行注释,但上下文中最多的是它所涉及的实体能需要旧的价值观。或实体的提取ID。或者其他元数据。所有这些都不为JPA所支持。因此,您需要实现Hibernate接口,如PreDeleteEventListener、PreUpdateEventListener、PostInsertEventListener等,并获取它们的XEvent对象。

但是如果您使用的是JPA,那么您很难让这些监听器实现Spring管理和注册。您可以将它们作为类名列出,但是Hibernate会实例化它们。下面是您需要进行的调整,以使此工作正常进行:

首先,扩展持久性提供程序:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

public class HibernateExtendedPersistenceProvider extends HibernatePersistence {

    private PostInsertEventListener[] postInsertEventListeners;

    private PreUpdateEventListener[] preUpdateEventListeners;

    private PreDeleteEventListener[] preDeleteEventListeners;

     

    @SuppressWarnings("rawtypes")

    @Override

    public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {

        Ejb3Configuration cfg = new Ejb3Configuration();

        setupConfiguration(cfg);

        Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );

        return configured != null ? configured.buildEntityManagerFactory() : null;

    }

    @SuppressWarnings("rawtypes")

    @Override

    public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {

        Ejb3Configuration cfg = new Ejb3Configuration();

        setupConfiguration(cfg);

        Ejb3Configuration configured = cfg.configure( info, properties );

        return configured != null ? configured.buildEntityManagerFactory() : null;

    }

     

    private void setupConfiguration(Ejb3Configuration cfg) {

        cfg.getEventListeners().setPostInsertEventListeners(postInsertEventListeners);

        cfg.getEventListeners().setPreDeleteEventListeners(preDeleteEventListeners);

        cfg.getEventListeners().setPreUpdateEventListeners(preUpdateEventListeners);

        //TODO if others are needed - add them

    }

    public void setPostInsertEventListeners(PostInsertEventListener[] postInsertEventListeners) {

        this.postInsertEventListeners = postInsertEventListeners;

    }

    public void setPreUpdateEventListeners(PreUpdateEventListener[] preUpdateEventListeners) {

        this.preUpdateEventListeners = preUpdateEventListeners;

    }

    public void setPreDeleteEventListeners(PreDeleteEventListener[] preDeleteEventListeners) {

        this.preDeleteEventListeners = preDeleteEventListeners;

    }

}

然后用@Component注释侦听器(或者按照您喜欢的方式将它们声明为Springbean)。然后登记:


https://www.douban.com/doulist/146069852/

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<bean id="hibernatePersistenceProvider" class="com.foo.bar.configuration.HibernateExtendedPersistenceProvider">

        <property name="postInsertEventListeners">

            <list>

                <ref bean="hibernateAuditLogListener" />

            </list>

        </property>

        <property name="preUpdateEventListeners">

            <list>

                <ref bean="hibernateAuditLogListener" />

            </list>

        </property>

        <property name="preDeleteEventListeners">

            <list>

                <ref bean="hibernateAuditLogListener" />

            </list>

        </property>

    </bean>

最后,将自定义持久性提供程序设置为实体管理器工厂bean:

https://movie.douban.com/doulist/146069852/

1

2

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="persistenceProvider" ref="hibernatePersistenceProvider" />

你刚才做的事:

  • 利用PersistenceProvider允许您获得Hibernate配置对象这一事实,在使用JPA时无法访问该配置对象
  • 将侦听器注册为Springbean,并将它们添加到扩展持久性提供程序,后者将它们注册为Hibernate。
  • 设置Spring的LocalContainerEntityManagerFactoryBean的“PersistenceProvider”属性。通常您不会设置它,因为它是从供应商适配器或类路径推断出来的。

https://www.imdb.com/list/ls550567867/

有一天,我意识到我的Tomcat默认使用块传输编码(HTTP1.1)。我不知道其他的服务器/容器/框架/语言,但是用块发送页面并不少见,比如Facebook就这样做了。“分块”的意思是服务器发送它已经准备好的页面片段,以便浏览器在服务器处理下一个块时呈现它们。

在JSP(可能在许多其他视图技术中)中有一个缓冲区--每当缓冲区被填充时,它就会被刷新到客户端。这意味着所有的头和第一个信息块(即缓冲区的内容)一起被发送。

但是有一个警告--如果服务器处理第二个(或任何后续)块时发生错误,会发生什么?您可能希望服务器将错误页发送到浏览器,但它不能这样工作:

  • 您不能重定向(发送位置标头),因为标题和响应状态已经发送。(你不能,当然服务器不能)
  • 您不能进行服务器端重定向(前进),因为新页面必须在已经发送的部分之后呈现--它看起来肯定很难看。

我想知道该怎么办,便堆积如山。显然,没有什么好办法摆脱这种局面。我所做的就是将这个片段发送到浏览器,然后浏览器重定向到错误页面:

1

</script><script>window.href.location="errorPage"</script>

特别是在JSP中是如何做到这一点的:<%@ page errorPage="/error/redirector.jsp" %>,并且redirector.jsp包含上面的脚本标记。为什么我们要从结束脚本标签开始呢?可能已经呈现的块中有一个打开的脚本标记,所以我们必须关闭它。丑陋,我知道,但似乎没有别的办法。

另一个问题出现了--我们这里是否需要分块的编码,难道它不适合下载的大型文件吗?这是一个单独的讨论,但由于Tomcat使用它作为默认的传输-编码,而Fa

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值