下面列出了怎么用org.springframework.orm.jpa.EntityManagerHolder的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void preHandle(WebRequest request) throws DataAccessException {
String key = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
if (asyncManager.hasConcurrentResult() && applyEntityManagerBindingInterceptor(asyncManager, key)) {
return;
}
EntityManagerFactory emf = obtainEntityManagerFactory();
if (TransactionSynchronizationManager.hasResource(emf)) {
// Do not modify the EntityManager: just mark the request accordingly.
Integer count = (Integer) request.getAttribute(key, WebRequest.SCOPE_REQUEST);
int newCount = (count != null ? count + 1 : 1);
request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
}
else {
logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
try {
EntityManager em = createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(emf, emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
asyncManager.registerCallableInterceptor(key, interceptor);
asyncManager.registerDeferredResultInterceptor(key, interceptor);
}
catch (PersistenceException ex) {
throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
}
}
}
@Override
public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException {
if (!decrementParticipateCount(request)) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
/**
* Binds an EMF to the thread and tests if EM with different properties
* generate new EMs or not.
*/
@Test
public void testPropertiesForSharedEntityManager1() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/ the properties)
given(mockEmf.createEntityManager(props)).willReturn(em);
given(em.getDelegate()).willReturn(new Object());
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessProperties(null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessProperties(null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/ properties will be created
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalField.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Test
public void testPropertiesForSharedEntityManager2() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/o the properties)
given(mockEmf.createEntityManager()).willReturn(em);
given(em.getDelegate()).willReturn(new Object(), 2);
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessProperties(null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessProperties(null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/o properties will be created
assertNotNull(transactionalField.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Override
public void preHandle(WebRequest request) throws DataAccessException {
String key = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
if (asyncManager.hasConcurrentResult() && applyEntityManagerBindingInterceptor(asyncManager, key)) {
return;
}
EntityManagerFactory emf = obtainEntityManagerFactory();
if (TransactionSynchronizationManager.hasResource(emf)) {
// Do not modify the EntityManager: just mark the request accordingly.
Integer count = (Integer) request.getAttribute(key, WebRequest.SCOPE_REQUEST);
int newCount = (count != null ? count + 1 : 1);
request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
}
else {
logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
try {
EntityManager em = createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(emf, emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
asyncManager.registerCallableInterceptor(key, interceptor);
asyncManager.registerDeferredResultInterceptor(key, interceptor);
}
catch (PersistenceException ex) {
throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
}
}
}
@Override
public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException {
if (!decrementParticipateCount(request)) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
/**
* Binds an EMF to the thread and tests if EM with different properties
* generate new EMs or not.
*/
@Test
public void testPropertiesForSharedEntityManager1() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/ the properties)
given(mockEmf.createEntityManager(props)).willReturn(em);
given(em.getDelegate()).willReturn(new Object());
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessProperties(null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessProperties(null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/ properties will be created
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalField.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Test
public void testPropertiesForSharedEntityManager2() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/o the properties)
given(mockEmf.createEntityManager()).willReturn(em);
given(em.getDelegate()).willReturn(new Object(), 2);
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessProperties(null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessProperties(null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/o properties will be created
assertNotNull(transactionalField.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Override
protected Connection getConnectionFromTransactionManager() {
EntityManager entityManager = createEntityManager();
Collection<JpaConnectionExtractor> jpaConnectionExtractors = NewInstanceServiceLoader.newServiceInstances(JpaConnectionExtractor.class);
if (jpaConnectionExtractors.isEmpty()) {
log.warn("Failed to get connection to proxy, caused by no JpaConnectionExtractor.");
throw new ShardingException("No JpaConnectionExtractor loaded");
}
Connection result = jpaConnectionExtractors.iterator().next().getConnectionFromEntityManager(entityManager);
TransactionSynchronizationManager.bindResource(transactionManager.getEntityManagerFactory(), new EntityManagerHolder(entityManager));
return result;
}
@Test
public void assertUnbindResource() {
EntityManagerHolder holder = mock(EntityManagerHolder.class);
EntityManager entityManager = entityManagerFactory.createEntityManager();
when(holder.getEntityManager()).thenReturn(entityManager);
TransactionSynchronizationManager.bindResource(entityManagerFactory, holder);
jpaTransactionManagerHandler.unbindResource();
assertNull(TransactionSynchronizationManager.getResource(entityManagerFactory));
}
@Override
public void preHandle(WebRequest request) throws DataAccessException {
String participateAttributeName = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
if (asyncManager.hasConcurrentResult()) {
if (applyCallableInterceptor(asyncManager, participateAttributeName)) {
return;
}
}
if (TransactionSynchronizationManager.hasResource(getEntityManagerFactory())) {
// Do not modify the EntityManager: just mark the request accordingly.
Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
int newCount = (count != null ? count + 1 : 1);
request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
}
else {
logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
try {
EntityManager em = createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(getEntityManagerFactory(), emHolder);
asyncManager.registerCallableInterceptor(participateAttributeName, interceptor);
asyncManager.registerDeferredResultInterceptor(participateAttributeName, interceptor);
}
catch (PersistenceException ex) {
throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
}
}
}
@Override
public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException {
if (!decrementParticipateCount(request)) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
/**
* close the entity manager.
* Use it with caution! This is only intended for use with async request, which Spring won't
* close the entity manager until the async request is finished.
*/
public void closeEntityManager() {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.getResource(getEntityManagerFactory());
if (emHolder == null) {
return;
}
logger.debug("Closing JPA EntityManager in EntityManagerUtil");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
@Override
public void preHandle(WebRequest request) throws DataAccessException {
String participateAttributeName = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
if (asyncManager.hasConcurrentResult()) {
if (applyCallableInterceptor(asyncManager, participateAttributeName)) {
return;
}
}
if (TransactionSynchronizationManager.hasResource(getEntityManagerFactory())) {
// Do not modify the EntityManager: just mark the request accordingly.
Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
int newCount = (count != null ? count + 1 : 1);
request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
}
else {
logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
try {
EntityManager em = createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(getEntityManagerFactory(), emHolder);
asyncManager.registerCallableInterceptor(participateAttributeName, interceptor);
asyncManager.registerDeferredResultInterceptor(participateAttributeName, interceptor);
}
catch (PersistenceException ex) {
throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
}
}
}
@Override
public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException {
if (!decrementParticipateCount(request)) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
/**
* Binds an EMF to the thread and tests if EM with different properties
* generate new EMs or not.
*/
@Test
public void testPropertiesForSharedEntityManager1() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/ the properties)
given(mockEmf.createEntityManager(props)).willReturn(em);
given(em.getDelegate()).willReturn(new Object());
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/ properties will be created
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalField.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Test
public void testPropertiesForSharedEntityManager2() {
Properties props = new Properties();
props.put("foo", "bar");
EntityManager em = mock(EntityManager.class);
// only one call made - the first EM definition wins (in this case the one w/o the properties)
given(mockEmf.createEntityManager()).willReturn(em);
given(em.getDelegate()).willReturn(new Object(), 2);
given(em.isOpen()).willReturn(true);
PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
pabpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
pabpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
// the EM w/o properties will be created
assertNotNull(transactionalField.em.getDelegate());
// bind em to the thread now since it's created
try {
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
verify(em).close();
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
}
@Before
public void doBefore(){
this.em = emf.createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(emf,
emHolder);
}
@Override
protected void doBegin(final Object transaction, final TransactionDefinition definition) {
super.doBegin(transaction, definition);
final String currentTenant = tenantAware.getCurrentTenant();
if (currentTenant != null) {
final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
.getResource(getEntityManagerFactory());
final EntityManager em = emHolder.getEntityManager();
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, currentTenant.toUpperCase());
}
}
public AsyncRequestInterceptor(EntityManagerFactory emFactory, EntityManagerHolder emHolder) {
this.emFactory = emFactory;
this.emHolder = emHolder;
}
@Test
public void testValidUsage() {
Object o = new Object();
EntityManager mockEm = mock(EntityManager.class);
given(mockEm.isOpen()).willReturn(true);
EntityManagerFactory mockEmf = mock(EntityManagerFactory.class);
given(mockEmf.createEntityManager()).willReturn(mockEm);
SharedEntityManagerBean proxyFactoryBean = new SharedEntityManagerBean();
proxyFactoryBean.setEntityManagerFactory(mockEmf);
proxyFactoryBean.afterPropertiesSet();
assertTrue(EntityManager.class.isAssignableFrom(proxyFactoryBean.getObjectType()));
assertTrue(proxyFactoryBean.isSingleton());
EntityManager proxy = proxyFactoryBean.getObject();
assertSame(proxy, proxyFactoryBean.getObject());
assertFalse(proxy.contains(o));
assertTrue(proxy instanceof EntityManagerProxy);
EntityManagerProxy emProxy = (EntityManagerProxy) proxy;
try {
emProxy.getTargetEntityManager();
fail("Should have thrown IllegalStateException outside of transaction");
}
catch (IllegalStateException ex) {
// expected
}
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(mockEm));
try {
assertSame(mockEm, emProxy.getTargetEntityManager());
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
verify(mockEm).contains(o);
verify(mockEm).close();
}
public AsyncRequestInterceptor(EntityManagerFactory emFactory, EntityManagerHolder emHolder) {
this.emFactory = emFactory;
this.emHolder = emHolder;
}
@Test
public void testValidUsage() {
Object o = new Object();
EntityManager mockEm = mock(EntityManager.class);
given(mockEm.isOpen()).willReturn(true);
EntityManagerFactory mockEmf = mock(EntityManagerFactory.class);
given(mockEmf.createEntityManager()).willReturn(mockEm);
SharedEntityManagerBean proxyFactoryBean = new SharedEntityManagerBean();
proxyFactoryBean.setEntityManagerFactory(mockEmf);
proxyFactoryBean.afterPropertiesSet();
assertTrue(EntityManager.class.isAssignableFrom(proxyFactoryBean.getObjectType()));
assertTrue(proxyFactoryBean.isSingleton());
EntityManager proxy = proxyFactoryBean.getObject();
assertSame(proxy, proxyFactoryBean.getObject());
assertFalse(proxy.contains(o));
assertTrue(proxy instanceof EntityManagerProxy);
EntityManagerProxy emProxy = (EntityManagerProxy) proxy;
try {
emProxy.getTargetEntityManager();
fail("Should have thrown IllegalStateException outside of transaction");
}
catch (IllegalStateException ex) {
// expected
}
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(mockEm));
try {
assertSame(mockEm, emProxy.getTargetEntityManager());
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
verify(mockEm).contains(o);
verify(mockEm).close();
}
@Override
public void unbindResource() {
EntityManagerHolder entityManagerHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResourceIfPossible(transactionManager.getEntityManagerFactory());
EntityManagerFactoryUtils.closeEntityManager(entityManagerHolder.getEntityManager());
}
public AsyncRequestInterceptor(EntityManagerFactory emFactory, EntityManagerHolder emHolder) {
this.emFactory = emFactory;
this.emHolder = emHolder;
}
public AsyncRequestInterceptor(EntityManagerFactory emFactory, EntityManagerHolder emHolder) {
this.emFactory = emFactory;
this.emHolder = emHolder;
}
@Test
public void testValidUsage() {
Object o = new Object();
EntityManager mockEm = mock(EntityManager.class);
given(mockEm.isOpen()).willReturn(true);
EntityManagerFactory mockEmf = mock(EntityManagerFactory.class);
given(mockEmf.createEntityManager()).willReturn(mockEm);
SharedEntityManagerBean proxyFactoryBean = new SharedEntityManagerBean();
proxyFactoryBean.setEntityManagerFactory(mockEmf);
proxyFactoryBean.afterPropertiesSet();
assertTrue(EntityManager.class.isAssignableFrom(proxyFactoryBean.getObjectType()));
assertTrue(proxyFactoryBean.isSingleton());
EntityManager proxy = proxyFactoryBean.getObject();
assertSame(proxy, proxyFactoryBean.getObject());
assertFalse(proxy.contains(o));
assertTrue(proxy instanceof EntityManagerProxy);
EntityManagerProxy emProxy = (EntityManagerProxy) proxy;
try {
emProxy.getTargetEntityManager();
fail("Should have thrown IllegalStateException outside of transaction");
}
catch (IllegalStateException ex) {
// expected
}
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(mockEm));
try {
assertSame(mockEm, emProxy.getTargetEntityManager());
}
finally {
TransactionSynchronizationManager.unbindResource(mockEmf);
}
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
verify(mockEm).contains(o);
verify(mockEm).close();
}
@After
public void doAfter(){
EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
.unbindResource(emf);
}