Package org.springframework.orm.jpa.support

Source Code of org.springframework.orm.jpa.support.PersistenceInjectionTests

/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.orm.jpa.support;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.PersistenceProperty;
import javax.persistence.PersistenceUnit;

import org.hibernate.ejb.HibernateEntityManager;
import org.junit.Ignore;
import org.junit.Test;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBeanTests;
import org.springframework.orm.jpa.DefaultJpaDialect;
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.stereotype.Repository;
import org.springframework.tests.context.SimpleMapScope;
import org.springframework.tests.mock.jndi.ExpectedLookupTemplate;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.SerializationTestUtils;

import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;

/**
* Unit tests for persistence context and persistence unit injection.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Phillip Webb
*/
public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanTests {

  @Test
  public void testPrivatePersistenceContextField() throws Exception {
    mockEmf = mock(EntityManagerFactory.class, withSettings().serializable());
    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
    gac.registerBeanDefinition(FactoryBeanWithPersistenceContextField.class.getName(),
        new RootBeanDefinition(FactoryBeanWithPersistenceContextField.class));
    gac.refresh();

    DefaultPrivatePersistenceContextField bean = (DefaultPrivatePersistenceContextField) gac.getBean(
        DefaultPrivatePersistenceContextField.class.getName());
    FactoryBeanWithPersistenceContextField bean2 = (FactoryBeanWithPersistenceContextField) gac.getBean(
        "&" + FactoryBeanWithPersistenceContextField.class.getName());
    assertNotNull(bean.em);
    assertNotNull(bean2.em);

    assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean.em));
    assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean2.em));
  }

  @Test
  public void testPrivateVendorSpecificPersistenceContextField() {
    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultVendorSpecificPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultVendorSpecificPrivatePersistenceContextField.class));
    gac.refresh();

    DefaultVendorSpecificPrivatePersistenceContextField bean = (DefaultVendorSpecificPrivatePersistenceContextField)
        gac.getBean(DefaultVendorSpecificPrivatePersistenceContextField.class.getName());
    assertNotNull(bean.em);
  }

  @Test
  public void testPublicExtendedPersistenceContextSetter() throws Exception {
    EntityManager mockEm = mock(EntityManager.class);
    given(mockEmf.createEntityManager()).willReturn(mockEm);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
    gac.refresh();

    DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
        DefaultPublicPersistenceContextSetter.class.getName());
    assertNotNull(bean.em);
  }

  @Test
  public void testPublicSpecificExtendedPersistenceContextSetter() throws Exception {
    EntityManagerFactory mockEmf2 = mock(EntityManagerFactory.class);
    EntityManager mockEm2 = mock(EntityManager.class);
    given(mockEmf2.createEntityManager()).willReturn(mockEm2);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.getDefaultListableBeanFactory().registerSingleton("unit2", mockEmf2);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(SpecificPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(SpecificPublicPersistenceContextSetter.class));
    gac.refresh();

    SpecificPublicPersistenceContextSetter bean = (SpecificPublicPersistenceContextSetter) gac.getBean(
        SpecificPublicPersistenceContextSetter.class.getName());
    assertNotNull(bean.getEntityManager());
    bean.getEntityManager().flush();
    verify(mockEm2).getTransaction();
    verify(mockEm2).flush();
  }

  @Test
  public void testInjectionIntoExistingObjects() {
    EntityManager mockEm = mock(EntityManager.class);
    given(mockEmf.createEntityManager()).willReturn(mockEm);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.refresh();

    DefaultPrivatePersistenceContextField existingBean1 = new DefaultPrivatePersistenceContextField();
    gac.getAutowireCapableBeanFactory().autowireBean(existingBean1);
    assertNotNull(existingBean1.em);

    DefaultPublicPersistenceContextSetter existingBean2 = new DefaultPublicPersistenceContextSetter();
    gac.getAutowireCapableBeanFactory().autowireBean(existingBean2);
    assertNotNull(existingBean2.em);
  }

  @Test
  public void testPublicExtendedPersistenceContextSetterWithSerialization() throws Exception {
    DummyInvocationHandler ih = new DummyInvocationHandler();
    Object mockEm = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {EntityManager.class}, ih);
    given(mockEmf.createEntityManager()).willReturn((EntityManager) mockEm);

    GenericApplicationContext gac = new GenericApplicationContext();
    SimpleMapScope myScope = new SimpleMapScope();
    gac.getDefaultListableBeanFactory().registerScope("myScope", myScope);
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class);
    bd.setScope("myScope");
    gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(), bd);
    gac.refresh();

    DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
        DefaultPublicPersistenceContextSetter.class.getName());
    assertNotNull(bean.em);
    assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean.em));

    SimpleMapScope serialized = (SimpleMapScope) SerializationTestUtils.serializeAndDeserialize(myScope);
    serialized.close();
    assertTrue(DummyInvocationHandler.closed);
    DummyInvocationHandler.closed = false;
  }

  @Test
  @SuppressWarnings("unchecked")
  public void testPublicExtendedPersistenceContextSetterWithEntityManagerInfoAndSerialization() throws Exception {
    EntityManager mockEm = mock(EntityManager.class, withSettings().serializable());
    given(mockEm.isOpen()).willReturn(true);
    EntityManagerFactoryWithInfo mockEmf = mock(EntityManagerFactoryWithInfo.class);
    given(mockEmf.getNativeEntityManagerFactory()).willReturn(mockEmf);
    given(mockEmf.getJpaDialect()).willReturn(new DefaultJpaDialect());
    given(mockEmf.getEntityManagerInterface()).willReturn((Class)EntityManager.class);
    given(mockEmf.getBeanClassLoader()).willReturn(getClass().getClassLoader());
    given(mockEmf.createEntityManager()).willReturn(mockEm);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
    gac.refresh();

    DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
        DefaultPublicPersistenceContextSetter.class.getName());
    assertNotNull(bean.em);
    assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean.em));
  }

  @Test
  public void testPublicExtendedPersistenceContextSetterWithOverriding() {
    EntityManager mockEm2 = mock(EntityManager.class);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class);
    bd.getPropertyValues().add("entityManager", mockEm2);
    gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(), bd);
    gac.refresh();

    DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
        DefaultPublicPersistenceContextSetter.class.getName());
    assertSame(mockEm2, bean.em);
  }

  @Test
  public void testPrivatePersistenceUnitField() {
    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultPrivatePersistenceUnitField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceUnitField.class));
    gac.refresh();

    DefaultPrivatePersistenceUnitField bean = (DefaultPrivatePersistenceUnitField) gac.getBean(
        DefaultPrivatePersistenceUnitField.class.getName());
    assertSame(mockEmf, bean.emf);
  }

  @Test
  public void testPublicPersistenceUnitSetter() {
    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    gac.refresh();

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter) gac.getBean(
        DefaultPublicPersistenceUnitSetter.class.getName());
    assertSame(mockEmf, bean.emf);
  }

  @Test
  public void testPublicPersistenceUnitSetterWithOverriding() {
    EntityManagerFactory mockEmf2 = mock(EntityManagerFactory.class);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.registerBeanDefinition("annotationProcessor",
        new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
    RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class);
    bd.getPropertyValues().add("emf", mockEmf2);
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(), bd);
    gac.refresh();

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter) gac.getBean(
        DefaultPublicPersistenceUnitSetter.class.getName());
    assertSame(mockEmf2, bean.emf);
  }

  @Test
  public void testPublicPersistenceUnitSetterWithUnitIdentifiedThroughBeanName() {
    EntityManagerFactory mockEmf2 = mock(EntityManagerFactory.class);

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory2", mockEmf2);
    gac.registerAlias("entityManagerFactory2", "Person");
    RootBeanDefinition processorDef = new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class);
    processorDef.getPropertyValues().add("defaultPersistenceUnitName", "entityManagerFactory");
    gac.registerBeanDefinition("annotationProcessor", processorDef);
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
    gac.refresh();

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
        gac.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
    DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
        gac.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
    assertSame(mockEmf, bean.emf);
    assertSame(mockEmf2, bean2.emf);
  }

  @Test
  public void testPublicPersistenceUnitSetterWithMultipleUnitsIdentifiedThroughUnitName() {
    EntityManagerFactoryWithInfo mockEmf2 = mock(EntityManagerFactoryWithInfo.class);
    given(mockEmf2.getPersistenceUnitName()).willReturn("Person");

    GenericApplicationContext gac = new GenericApplicationContext();
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
    gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory2", mockEmf2);
    RootBeanDefinition processorDef = new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class);
    processorDef.getPropertyValues().add("defaultPersistenceUnitName", "entityManagerFactory");
    gac.registerBeanDefinition("annotationProcessor", processorDef);
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
    gac.refresh();

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
        gac.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
    DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
        gac.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
    assertSame(mockEmf, bean.emf);
    assertSame(mockEmf2, bean2.emf);
  }

  @Test
  @Ignore
  public void testPersistenceUnitsFromJndi() {
    EntityManager mockEm = mock(EntityManager.class);
    given(mockEmf.createEntityManager()).willReturn(mockEm);

    EntityManagerFactoryWithInfo mockEmf2 = mock(EntityManagerFactoryWithInfo.class);

    Map<String, String> persistenceUnits = new HashMap<String, String>();
    persistenceUnits.put("", "pu1");
    persistenceUnits.put("Person", "pu2");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pu1", mockEmf);
    jt.addObject("java:comp/env/pu2", mockEmf2);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceUnits(persistenceUnits);
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
        bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
    DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
        bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
    DefaultPrivatePersistenceContextField bean3 = (DefaultPrivatePersistenceContextField)
        bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
    DefaultPublicPersistenceContextSetter bean4 = (DefaultPublicPersistenceContextSetter)
        bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
    assertSame(mockEmf, bean.emf);
    assertSame(mockEmf2, bean2.emf);
    assertNotNull(bean3.em);
    assertNotNull(bean4.em);
  }

  @Test
  public void testPersistenceUnitsFromJndiWithDefaultUnit() {
    EntityManagerFactoryWithInfo mockEmf2 = mock(EntityManagerFactoryWithInfo.class);

    Map<String, String> persistenceUnits = new HashMap<String, String>();
    persistenceUnits.put("System", "pu1");
    persistenceUnits.put("Person", "pu2");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pu1", mockEmf);
    jt.addObject("java:comp/env/pu2", mockEmf2);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceUnits(persistenceUnits);
    bpp.setDefaultPersistenceUnitName("System");
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
        bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
    DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
        bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
    assertSame(mockEmf, bean.emf);
    assertSame(mockEmf2, bean2.emf);
  }

  @Test
  public void testSinglePersistenceUnitFromJndi() {
    Map<String, String> persistenceUnits = new HashMap<String, String>();
    persistenceUnits.put("Person", "pu1");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pu1", mockEmf);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceUnits(persistenceUnits);
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));

    DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
        bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
    DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
        bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
    assertSame(mockEmf, bean.emf);
    assertSame(mockEmf, bean2.emf);
  }

  @Test
  public void testPersistenceContextsFromJndi() {
    EntityManager mockEm = mock(EntityManager.class);
    EntityManager mockEm2 = mock(EntityManager.class);
    EntityManager mockEm3 = mock(EntityManager.class);

    Map<String, String> persistenceContexts = new HashMap<String, String>();
    persistenceContexts.put("", "pc1");
    persistenceContexts.put("Person", "pc2");
    Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
    extendedPersistenceContexts .put("", "pc3");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pc1", mockEm);
    jt.addObject("java:comp/env/pc2", mockEm2);
    jt.addObject("java:comp/env/pc3", mockEm3);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceContexts(persistenceContexts);
    bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));

    DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
        bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
    DefaultPrivatePersistenceContextFieldNamedPerson bean2 = (DefaultPrivatePersistenceContextFieldNamedPerson)
        bf.getBean(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName());
    DefaultPublicPersistenceContextSetter bean3 = (DefaultPublicPersistenceContextSetter)
        bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
    assertSame(mockEm, bean1.em);
    assertSame(mockEm2, bean2.em);
    assertSame(mockEm3, bean3.em);
  }

  @Test
  public void testPersistenceContextsFromJndiWithDefaultUnit() {
    EntityManager mockEm = mock(EntityManager.class);
    EntityManager mockEm2 = mock(EntityManager.class);
    EntityManager mockEm3 = mock(EntityManager.class);

    Map<String, String> persistenceContexts = new HashMap<String, String>();
    persistenceContexts.put("System", "pc1");
    persistenceContexts.put("Person", "pc2");
    Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
    extendedPersistenceContexts .put("System", "pc3");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pc1", mockEm);
    jt.addObject("java:comp/env/pc2", mockEm2);
    jt.addObject("java:comp/env/pc3", mockEm3);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceContexts(persistenceContexts);
    bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
    bpp.setDefaultPersistenceUnitName("System");
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));

    DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
        bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
    DefaultPrivatePersistenceContextFieldNamedPerson bean2 = (DefaultPrivatePersistenceContextFieldNamedPerson)
        bf.getBean(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName());
    DefaultPublicPersistenceContextSetter bean3 = (DefaultPublicPersistenceContextSetter)
        bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
    assertSame(mockEm, bean1.em);
    assertSame(mockEm2, bean2.em);
    assertSame(mockEm3, bean3.em);
  }

  @Test
  public void testSinglePersistenceContextFromJndi() {
    EntityManager mockEm = mock(EntityManager.class);
    EntityManager mockEm2 = mock(EntityManager.class);

    Map<String, String> persistenceContexts = new HashMap<String, String>();
    persistenceContexts.put("System", "pc1");
    Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
    extendedPersistenceContexts .put("System", "pc2");
    ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
    jt.addObject("java:comp/env/pc1", mockEm);
    jt.addObject("java:comp/env/pc2", mockEm2);

    DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
    PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
    bpp.setPersistenceContexts(persistenceContexts);
    bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
    bpp.setJndiTemplate(jt);
    bf.addBeanPostProcessor(bpp);
    bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
        new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
    bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
        new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));

    DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
        bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
    DefaultPublicPersistenceContextSetter bean2 = (DefaultPublicPersistenceContextSetter)
        bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
    assertSame(mockEm, bean1.em);
    assertSame(mockEm2, bean2.em);
  }

  @Test
  public void testFieldOfWrongTypeAnnotatedWithPersistenceUnit() {
    PersistenceAnnotationBeanPostProcessor pabpp = new PersistenceAnnotationBeanPostProcessor();
    try {
      pabpp.postProcessPropertyValues(null, null, new FieldOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
      fail("Can't inject this field");
    }
    catch (IllegalStateException ex) {
      // Ok
    }
  }

  @Test
  public void testSetterOfWrongTypeAnnotatedWithPersistenceUnit() {
    PersistenceAnnotationBeanPostProcessor pabpp = new PersistenceAnnotationBeanPostProcessor();
    try {
      pabpp.postProcessPropertyValues(null, null, new SetterOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
      fail("Can't inject this setter");
    }
    catch (IllegalStateException ex) {
      // Ok
    }
  }

  @Test
  public void testSetterWithNoArgs() {
    PersistenceAnnotationBeanPostProcessor pabpp = new PersistenceAnnotationBeanPostProcessor();
    try {
      pabpp.postProcessPropertyValues(null, null, new SetterWithNoArgs(), "bean");
      fail("Can't inject this setter");
    }
    catch (IllegalStateException ex) {
      // Ok
    }
  }

  @Test
  public void testNoPropertiesPassedIn() {
    EntityManager mockEm = mock(EntityManager.class);
    given(mockEmf.createEntityManager()).willReturn(mockEm);

    PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
    DefaultPrivatePersistenceContextFieldExtended dppcf = new DefaultPrivatePersistenceContextFieldExtended();
    pabpp.postProcessPropertyValues(null, null, dppcf, "bean");
    assertNotNull(dppcf.em);
  }

  @Test
  public void testPropertiesPassedIn() {
    Properties props = new Properties();
    props.put("foo", "bar");
    EntityManager mockEm = mock(EntityManager.class);
    given(mockEmf.createEntityManager(props)).willReturn(mockEm);

    PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
    DefaultPrivatePersistenceContextFieldExtendedWithProps dppcf =
        new DefaultPrivatePersistenceContextFieldExtendedWithProps();
    pabpp.postProcessPropertyValues(null, null, dppcf, "bean");
    assertNotNull(dppcf.em);
  }

  @Test
  public void testPropertiesForTransactionalEntityManager() {
    Properties props = new Properties();
    props.put("foo", "bar");
    EntityManager em = mock(EntityManager.class);
    given(mockEmf.createEntityManager(props)).willReturn(em);
    given(em.getDelegate()).willReturn(new Object());
    given(em.isOpen()).willReturn(true);

    PersistenceAnnotationBeanPostProcessor pabpp = new MockPersistenceAnnotationBeanPostProcessor();
    DefaultPrivatePersistenceContextFieldWithProperties transactionalField =
        new DefaultPrivatePersistenceContextFieldWithProperties();
    pabpp.postProcessPropertyValues(null, null, transactionalField, "bean");

    assertNotNull(transactionalField.em);
    assertNotNull(transactionalField.em.getDelegate());

    verify(em).close();
  }

  /**
   * 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);
    }
  }


  @SuppressWarnings("serial")
  private static class MockPersistenceAnnotationBeanPostProcessor extends PersistenceAnnotationBeanPostProcessor {

    @Override
    protected EntityManagerFactory findEntityManagerFactory(String emfName, String requestingBeanName) {
      return mockEmf;
    }
  }


  public static class DefaultPrivatePersistenceContextField {

    @PersistenceContext
    private EntityManager em;
  }


  public static class DefaultVendorSpecificPrivatePersistenceContextField {

    @PersistenceContext
    private HibernateEntityManager em;
  }


  public static class FactoryBeanWithPersistenceContextField implements FactoryBean {

    @PersistenceContext
    private EntityManager em;

    @Override
    public Object getObject() throws Exception {
      return null;
    }

    @Override
    public Class getObjectType() {
      return null;
    }

    @Override
    public boolean isSingleton() {
      return true;
    }
  }


  public static class DefaultPrivatePersistenceContextFieldNamedPerson {

    @PersistenceContext(unitName = "Person")
    private EntityManager em;
  }


  public static class DefaultPrivatePersistenceContextFieldWithProperties {

    @PersistenceContext(properties = { @PersistenceProperty(name = "foo", value = "bar") })
    private EntityManager em;
  }


  @Repository
  @SuppressWarnings("serial")
  public static class DefaultPublicPersistenceContextSetter implements Serializable {

    private EntityManager em;

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    public void setEntityManager(EntityManager em) {
      if (this.em != null) {
        throw new IllegalStateException("Already called");
      }
      this.em = em;
    }

    public EntityManager getEntityManager() {
      return em;
    }
  }


  @SuppressWarnings("serial")
  public static class SpecificPublicPersistenceContextSetter extends DefaultPublicPersistenceContextSetter {

    @Override
    @PersistenceContext(unitName="unit2", type = PersistenceContextType.EXTENDED)
    public void setEntityManager(EntityManager em) {
      super.setEntityManager(em);
    }
  }


  public static class DefaultPrivatePersistenceUnitField {

    @PersistenceUnit
    private EntityManagerFactory emf;
  }


  public static class DefaultPublicPersistenceUnitSetter {

    private EntityManagerFactory emf;

    @PersistenceUnit
    public void setEmf(EntityManagerFactory emf) {
      if (this.emf != null) {
        throw new IllegalStateException("Already called");
      }
      this.emf = emf;
    }

    public EntityManagerFactory getEmf() {
      return emf;
    }
  }


  @Repository
  public static class DefaultPublicPersistenceUnitSetterNamedPerson {

    private EntityManagerFactory emf;

    @PersistenceUnit(unitName = "Person")
    public void setEmf(EntityManagerFactory emf) {
      this.emf = emf;
    }

    public EntityManagerFactory getEntityManagerFactory() {
      return emf;
    }
  }


  public static class FieldOfWrongTypeAnnotatedWithPersistenceUnit {

    @PersistenceUnit
    public String thisFieldIsOfTheWrongType;
  }


  public static class SetterOfWrongTypeAnnotatedWithPersistenceUnit {

    @PersistenceUnit
    public void setSomething(Comparable c) {
    }
  }


  public static class SetterWithNoArgs {

    @PersistenceUnit
    public void setSomething() {
    }
  }


  public static class DefaultPrivatePersistenceContextFieldExtended {

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;
  }


  public static class DefaultPrivatePersistenceContextFieldExtendedWithProps {

    @PersistenceContext(type = PersistenceContextType.EXTENDED, properties = { @PersistenceProperty(name = "foo", value = "bar") })
    private EntityManager em;
  }


  private interface EntityManagerFactoryWithInfo extends EntityManagerFactory, EntityManagerFactoryInfo {

  }


  @SuppressWarnings("serial")
  private static class DummyInvocationHandler implements InvocationHandler, Serializable {

    public static boolean closed;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      if ("isOpen".equals(method.getName())) {
        return true;
      }
      if ("close".equals(method.getName())) {
        closed = true;
        return null;
      }
      if ("toString".equals(method.getName())) {
        return "";
      }
      throw new IllegalStateException();
    }
  }
}
TOP

Related Classes of org.springframework.orm.jpa.support.PersistenceInjectionTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.