【问题标题】:Having a separate persistence.xml file for testing有一个单独的 persistence.xml 文件进行测试
【发布时间】:2017-01-21 04:53:53
【问题描述】:

受这个问题的启发:JPA using alternative "persistence.xml" 我创建了一个文件夹结构,如下所示:

  • src/main/resources/META-INF/persistence.xml
  • src/test/resources/META-INF/persistence.xml

两个persistence-units 具有相同的名称,因为我的目标是测试应该选择test-folder 中的那个,否则应该使用“normal”那个。 上述问题的答案声称“Maven将测试类/资源放在类路径中的主要类/资源之前” 然而,这不是我所看到的。如果persistence-units 同名,则始终使用src/main/resources/ 中的那个...

任何有关如何解决此问题的建议将不胜感激

【问题讨论】:

  • 如何创建 EntityManagerFactory?
  • EntityManager em = Persistence.createEntityManagerFactory("pu").createEntityManager();
  • 使用 Maven 运行时,它会将资源复制到目标,而不是使用 src 下的资源
  • 它对我有用
  • 是的,但是如果上一个问题中的陈述是正确的,那么测试阶段的 Maven 会首先读取测试资源(这就是我的阅读方式),拥有单独的持久性真的很酷用于单元测试的 .xml 文件。但我想,这就是我所观察到的,这不是真的?

标签: java jpa eclipselink maven-3


【解决方案1】:

所以看来对原引用问题的回复是错误的?所以我最终采用了另一种策略,如下所示: 我有一个静态类,它总是用于获取持久性单元的名称以供使用。

public class PU_Name
{
  private static String puName = "pu_delopment";

  public static String getPU_Name(){
    return puName;
  }
  public static void setPU_Name(String name){
    puName = name;
  }
}

每当我创建一个 EntityManager 时,我都会按照下面的草图进行操作。在此示例中,它更改名称以使用“测试持久性单元”

@BeforeClass
public static void initClass(){
  PU_Name.setPU_Name("puTest");
  emf = Persistence.createEntityManagerFactory(PU.getPU_Name());
}

真正的类更“高级”一些,因为它还检测到 OPENSHIFT 环境变量的存在并转移到使用“生产”数据库的持久性单元。

【讨论】:

    【解决方案2】:

    我有同样的情况,在测试和主要资源中有两个persistence.xml。始终无法检测到测试类路径中的唯一 PU 名称,即使我确保 hiberante-entitymanager 并且测试文件位于类路径中。

    最后我找到了一个解决方案:以编程方式构造 entityManagerFactory,如下所示:create entity manager programmatically without persistence file

    所以我做了非常相似的事情:

        @BeforeClass
        public static void prepare() {
            Map<String, Object> configOverrides = new HashMap<>();
            configOverrides.put("hibernate.connection.driver_class", "org.h2.Driver");
            configOverrides.put("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
            configOverrides.put("hibernate.connection.username", "sa");
            configOverrides.put("hibernate.connection.password", "sa");
            configOverrides.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
            configOverrides.put("hibernate.show_sql", "true");
            configOverrides.put("hibernate.hbm2ddl.auto", "validate");
            //factory = new HibernatePersistence().createContainerEntityManagerFactory(
            //        new CustomPersistenceUnitInfo(), configOverrides
            //);
            factory = Persistence.createEntityManagerFactory("test");
            assertNotNull(factory);
        }
    ...
        private static class CustomPersistenceUnitInfo implements PersistenceUnitInfo {
    
            @Override
            public String getPersistenceUnitName() {
                return "test";
            }
    
            @Override
            public String getPersistenceProviderClassName() {
                return "org.hibernate.jpa.HibernatePersistenceProvider";
     // <------------note here: this is wrong!
            }
    
            @Override
            public PersistenceUnitTransactionType getTransactionType() {
                return PersistenceUnitTransactionType.RESOURCE_LOCAL;
            }
    
            @Override
            public DataSource getJtaDataSource() {
                return null;
            }
    
            @Override
            public DataSource getNonJtaDataSource() {
                return null;
            }
    
            @Override
            public List<String> getMappingFileNames() {
                return Collections.emptyList();
            }
    
            @Override
            public List<URL> getJarFileUrls() {
                try {
                    return Collections.list(this.getClass()
                            .getClassLoader()
                            .getResources(""));
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }
    
            @Override
            public URL getPersistenceUnitRootUrl() {
                return null;
            }
    
            @Override
            public List<String> getManagedClassNames() {
                return Arrays.asList(
                        "com.app.Entity1",
                        "com.app.Entity2"
                );
            }
    
            @Override
            public boolean excludeUnlistedClasses() {
                return true;
            }
    
            @Override
            public SharedCacheMode getSharedCacheMode() {
                return null;
            }
    
            @Override
            public ValidationMode getValidationMode() {
                return null;
            }
    
            @Override
            public Properties getProperties() {
                return null;
            }
    
            @Override
            public String getPersistenceXMLSchemaVersion() {
                return null;
            }
    
            @Override
            public ClassLoader getClassLoader() {
                return null;
            }
    
            @Override
            public void addTransformer(final ClassTransformer classTransformer) {
    
            }
    
            @Override
            public ClassLoader getNewTempClassLoader() {
                return null;
            }
        }
    
    
    

    然后,我发现它仍然返回null。为什么?然后我发现在com.hibernate.ejb.HibernatePersistence类中,provider应该不是com.hibernate.jpa.HibernatePersistenceProvider,而是com.hibernate.ejb.HibernatePersistencHibernatePersistenceProvider 类甚至不在我的类路径中。

    Ejb3Configuration.class:

            integration = integration != null ? Collections.unmodifiableMap(integration) : CollectionHelper.EMPTY_MAP;
            String provider = (String)integration.get("javax.persistence.provider");
            if (provider == null) {
                provider = info.getPersistenceProviderClassName();
            }
    
            if (provider != null && !provider.trim().startsWith(IMPLEMENTATION_NAME)) { // private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName(); which, is, "com.hibernate.ejb.HibernatePersistence"
                LOG.requiredDifferentProvider(provider);
                return null;
            } else {
    

    所以我回到了第一个解决方案,并更改了提供商名称,现在它可以工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 2017-05-04
      • 2022-01-15
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多