【问题标题】:How to inject hibernate metamodel in spring test context without full hibernate connection?如何在没有完全休眠连接的情况下在弹簧测试上下文中注入休眠元模型?
【发布时间】:2016-04-26 11:17:31
【问题描述】:

我有实体。

@Entity
class Foo {
    @Column
    Long id;
    /* ... */
}

Hibernate 为其生成 Metamodel:

@StaticMetamodel(Foo.class)
public abstract class Foo_ {
    public static volatile SingularAttribute<Foo, Long> id;
    /* ... */
}

我想做一些测试没有数据库连接。但我需要获取Foo_.id.getName() 的值以用于反射。

不幸的是,它在测试环境中不起作用。此测试失败

@Test
public void metaModelTest() {
    Assert.assertTrue(Foo_.id != null);
}

我在这里找到:JPA/Hibernate Static Metamodel Attributes not Populated -- NullPointerException

当构建 Hibernate EntityManagerFactory 时,它会为每个已知的托管类型寻找一个规范的元模型类,如果找到,它将向它们注入适当的元模型信息,如 [JPA 2 规范中所述,第 6.2.2 节,第 200 页]

有没有办法让模拟 EntityManagerFactory 做到这一点?或许还有其他解决方案?

注意: 测试在 Spring 测试上下文中。

【问题讨论】:

    标签: java spring hibernate metamodel


    【解决方案1】:

    我目前的解决办法是这样的:

    @Component
    @SuppressWarnings({ "rawtypes", "unchecked", "serial" })
    public class MockMetaModelGenerator {
        private static final String BASE_PACKAGE = "com.example.foo";
    
        @PostConstruct
        public void init() {
            ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
            scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
            for (BeanDefinition bd : scanner.findCandidateComponents(BASE_PACKAGE)) {
                Class<?> metamodel;
                try {
                    metamodel = Thread.currentThread().getContextClassLoader().loadClass(bd.getBeanClassName() + "_");
                    for (Field field : metamodel.getFields()) {
                        field.set(null, new GenericAttrImpl(field.getName()));
                    }
                } catch (Exception e) {
                    Throwables.propagate(e);
                }
            }
        }
    
        static class GenericAttrImpl extends AbstractAttribute implements CollectionAttribute, SetAttribute, ListAttribute, MapAttribute,
                SingularAttribute {
            GenericAttrImpl(String name) {
                super(name, null, null, null, null);
            }
            /* Mock realization of other methods */
        }
    }
    

    pastebin 上的完整代码:http://pastebin.com/Ncc8Ty46

    丑陋但有效。

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 2016-11-04
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      相关资源
      最近更新 更多