zoukankan      html  css  js  c++  java
  • SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-003编写JPA-based repository( @PersistenceUnit、 @PersistenceContext、PersistenceAnnotationBeanPostProcessor)

    一、注入EntityManagerFactory的方式

     1 package com.habuma.spittr.persistence;
     2 import java.util.List;
     3 import javax.persistence.EntityManagerFactory;
     4 import javax.persistence.PersistenceUnit;
     5 import org.springframework.dao.DataAccessException;
     6 import org.springframework.stereotype.Repository;
     7 import org.springframework.transaction.annotation.Transactional;
     8 import com.habuma.spittr.domain.Spitter;
     9 import com.habuma.spittr.domain.Spittle;
    10 @Repository
    11 @Transactional
    12 public class JpaSpitterRepository implements SpitterRepository {
    13     @PersistenceUnit
    14     private EntityManagerFactory emf;
    15     public void addSpitter(Spitter spitter) {
    16         emf.createEntityManager().persist(spitter);
    17     }
    18     public Spitter getSpitterById(long id) {
    19         return emf.createEntityManager().find(Spitter.class, id);
    20     }
    21     public void saveSpitter(Spitter spitter) {
    22         emf.createEntityManager().merge(spitter);
    23     }
    24         ...
    25 }

    这种方式有一个问题,Aside from presenting a troubling code-duplication situation, it also means a new EntityManager is created every time one ofthe repository methods is called. This complicates matters concerning transactions.

    二、注入EntityManager的方式(其实并注入代理)

    若用注入EntityManager的方式,也有一个问题,The problem is that an EntityManager isn’t thread-safe and generally shouldn’t be injected into a shared singleton bean like your repository. But that doesn’t mean you can’t ask for an EntityManager anyway.

     1 package com.habuma.spittr.persistence;
     2 import java.util.List;
     3 import javax.persistence.EntityManager;
     4 import javax.persistence.PersistenceContext;
     5 import org.springframework.dao.DataAccessException;
     6 import org.springframework.stereotype.Repository;
     7 import org.springframework.transaction.annotation.Transactional;
     8 import com.habuma.spittr.domain.Spitter;
     9 import com.habuma.spittr.domain.Spittle;
    10 @Repository
    11 @Transactional
    12 public class JpaSpitterRepository implements SpitterRepository {
    13     @PersistenceContext
    14     private EntityManager em;
    15     public void addSpitter(Spitter spitter) {
    16         em.persist(spitter);
    17     }
    18     public Spitter getSpitterById(long id) {
    19         return em.find(Spitter.class, id);
    20     }
    21     public void saveSpitter(Spitter spitter) {
    22             em.merge(spitter);
    23         }
    24         ...
    25 }

    关于线程的安全问题,The truth is that @PersistenceContext doesn’t inject an EntityManager —at least,not exactly. Instead of giving the repository a real EntityManager , it gives a proxy to a real EntityManager . That real EntityManager either is one associated with the current transaction or, if one doesn’t exist, creates a new one. Thus, you know that you’re

    always working with an entity manager in a thread-safe way.

     @PersistenceUnit and  @PersistenceContext是JPA的标准,要让Spring明白这两个标签的注入方式,则要配置PersistenceAnnotationBeanPostProcessor,但若是使用 <context:annotation-config> or  <context:component-scan> ,则默认是已经配置了的

    1 @Bean
    2 public PersistenceAnnotationBeanPostProcessor paPostProcessor() {
    3     return new PersistenceAnnotationBeanPostProcessor();
    4 }

    @Transactional indicates that the persistence methods in this repository are involved in a transactional context.

  • 相关阅读:
    辅助构造器
    pycharm、webstorm和idea激活码
    Executor
    生产者和消费者模型
    Master和worker模式
    Future模式
    记事本中快速查看数字对应的ASCII
    C#中时间戳和日期相互转换
    Dos命令调用FlashFXP上传文件
    curl 上传文件
  • 原文地址:https://www.cnblogs.com/shamgod/p/5344763.html
Copyright © 2011-2022 走看看