我有模块A和模块B,它们都有JPA注解的类。模块B有一个单元测试,它从A中拉入几个这样的实体。两个模块都编译得很好,运行时依赖关系也设置得很好,但是当我尝试运行单元测试时,我得到了以下错误:
java.lang.IllegalArgumentException: Unknown entity: MyClassHere
Caused by: org.hibernate.MappingException: Unknown entity: MyClassHere
这发生在EntityManager.merge调用中。
由于模块B有所有的hibernate配置文件等,我猜它根本不能从A中提取我的类是一个实体。
我尝试将以下内容添加到persistence.xml中
<exclude-unlisted-classes>false</exclude-unlisted-classes>
在hibernate.cfg.xml中,我添加了:
<property name="packagesToScan">myNamespace.*</property>
然后:
<property name="packagesToScan">
<array>
<value>myNamespace.*</value>
</array>
</property>
这给了我一个错误,即"property“的内容必须匹配null。然后我试着:
<mapping class="myNamespace.*" />
我遗漏了什么?
我忘记提到的一件事可能很重要,那就是这两个模块被设置为单独的项目(我使用的是),所以目录结构是不同的。运行时依赖项都设置正确,但由于.class文件最终位于不同的目录中,我认为hibernate可能不会扫描这些文件。
发布于 2015-10-24 17:59:02
如果您将项目配置为自动检测实体,它将只扫描META-INF/persistence.xml所在的路径(默认情况下)。
除了:
<exclude-unlisted-classes>false</exclude-unlisted-classes>
您可以设置一个额外的休眠选项:
<property name="hibernate.archive.autodetection" value="class, hbm" />
它确定Hibernate Entity Manager自动发现哪个元素。
对于额外的实体(在其他jar中),您可以在主persistence.xml文件中设置jar文件部分:
<persistence>
<persistence-unit name="myUnit">
...
<class>foo.bar.Entity1</class>
<class>foo.bar.Entity2</class>
<jar-file>moduleB.jar</jar-file>
...
</persistence-unit>
</persistence>
jar-file元素指定对包含托管持久性类的封装持久性单元可见的JAR文件,而class元素显式命名托管持久性类。
META-INF目录包含persistence.xml的JAR文件或目录称为持久性单元的根。持久性单元的作用域由持久性单元的根确定。每个持久性单元都必须使用对于持久性单元的作用域唯一的名称进行标识。
向您致敬,安德烈
发布于 2016-01-25 13:38:30
发布于 2018-02-23 01:31:47
做到这一点的简单方法
configuration.addAnnotatedClass(Contact.class)
如果你想使用scan by package,首先使用ClassLoader
加载所有类。请参阅Hibernate-orm
LocalSessionFactoryBuilder.class中的示例源代码
@Bean
public SessionFactory sessionFactory(){
HibernateConfig configuration = new HibernateConfig();
Properties properties = hibernateProperties();
configuration.setProperties(properties);
configuration.scanPackages("com.atcc.stom.model.entity");
return configuration.buildSessionFactory();
}
HibernateConfig.class
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.ClassUtils;
import javax.persistence.AttributeConverter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Set;
import java.util.TreeSet;
public class HibernateConfig extends Configuration {
private static final TypeFilter[] DEFAULT_ENTITY_TYPE_FILTERS = new TypeFilter[] {
new AnnotationTypeFilter(Entity.class, false),
new AnnotationTypeFilter(Embeddable.class, false),
new AnnotationTypeFilter(MappedSuperclass.class, false)};
private static final String RESOURCE_PATTERN = "/**/*.class";
private static final String PACKAGE_INFO_SUFFIX = ".package-info";
private final ResourcePatternResolver resourcePatternResolver;
private static TypeFilter converterTypeFilter;
static {
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> converterAnnotation = (Class<? extends Annotation>)
ClassUtils.forName("javax.persistence.Converter", Configuration.class.getClassLoader());
converterTypeFilter = new AnnotationTypeFilter(converterAnnotation, false);
}
catch (ClassNotFoundException ex) {
// JPA 2.1 API not available - Hibernate <4.3
}
}
public HibernateConfig() {
this(new PathMatchingResourcePatternResolver());
}
public HibernateConfig(ClassLoader classLoader) {
this(new PathMatchingResourcePatternResolver(classLoader));
}
public HibernateConfig(ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
}
public void scanPackages(String... packagesToScan) throws HibernateException {
Set<String> entityClassNames = new TreeSet<String>();
Set<String> converterClassNames = new TreeSet<String>();
Set<String> packageNames = new TreeSet<String>();
try {
for (String pkg : packagesToScan) {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN;
Resource[] resources = this.resourcePatternResolver.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
String className = reader.getClassMetadata().getClassName();
if (matchesEntityTypeFilter(reader, readerFactory)) {
entityClassNames.add(className);
}
else if (converterTypeFilter != null && converterTypeFilter.match(reader, readerFactory)) {
converterClassNames.add(className);
}
else if (className.endsWith(PACKAGE_INFO_SUFFIX)) {
packageNames.add(className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length()));
}
}
}
}
}
catch (IOException ex) {
throw new MappingException("Failed to scan classpath for unlisted classes", ex);
}
try {
ClassLoader cl = this.resourcePatternResolver.getClassLoader();
for (String className : entityClassNames) {
addAnnotatedClass(cl.loadClass(className));
}
for (String className : converterClassNames) {
ConverterRegistrationDelegate.registerConverter(this, cl.loadClass(className));
}
for (String packageName : packageNames) {
addPackage(packageName);
}
}
catch (ClassNotFoundException ex) {
throw new MappingException("Failed to load annotated classes from classpath", ex);
}
}
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
for (TypeFilter filter : DEFAULT_ENTITY_TYPE_FILTERS) {
if (filter.match(reader, readerFactory)) {
return true;
}
}
return false;
}
/**
* Inner class to avoid hard dependency on JPA 2.1 / Hibernate 4.3.
*/
private static class ConverterRegistrationDelegate {
@SuppressWarnings("unchecked")
public static void registerConverter(Configuration config, Class<?> converterClass) {
config.addAttributeConverter((Class<? extends AttributeConverter<?, ?>>) converterClass);
}
}
}
https://stackoverflow.com/questions/33305823
复制相似问题