Spring5+Hibernate5实体映射异常:Tomcat部署AnnotationException排查
嘿,我来帮你排查这个头疼的问题——这种org.hibernate.AnnotationException几乎都是因为Hibernate找不到关联实体的映射信息导致的,结合你用Hibernate Tools生成实体、部署到Tomcat的场景,大概率是下面几个原因之一,咱们一个个来核对:
1. Referaty实体没被Hibernate纳入扫描范围
Hibernate要管理实体类,必须明确知道哪些类是它的“管辖范围”。你得检查两种配置方式:
- 如果你用Spring配置类来初始化Hibernate:确保
LocalSessionFactoryBean的setPackagesToScan方法包含了Referaty所在的包(比如com.example.model)。示例代码应该是这样的:@Bean public LocalSessionFactoryBean sessionFactory(DataSource dataSource) { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource); // 这里必须覆盖所有实体类所在的包 sessionFactory.setPackagesToScan("com.example.model"); sessionFactory.setHibernateProperties(getHibernateProperties()); return sessionFactory; } - 如果你用hibernate.cfg.xml配置:一定要在文件里添加
<mapping class="com.example.model.Referaty"/>,不然Hibernate根本不知道这个类是实体。
2. Referaty实体缺少核心JPA注解
虽然你是用Hibernate Tools生成的实体,但偶尔工具可能会抽风漏掉关键注解。赶紧打开Referaty类,检查顶部有没有@Entity注解——这是标记类为Hibernate实体的核心标识,最好再配上@Table指定对应的数据表(如果表名和类名不一致的话)。比如:
@Entity @Table(name = "referaty") // 对应数据库中的表名 public class Referaty implements Serializable { // 字段、主键注解、关联注解... }
另外,实体类最好实现Serializable接口,虽然这不是导致当前异常的直接原因,但也是Hibernate实体的常规要求。
3. Tomcat部署的war包中缺失Referaty类文件
部署到Tomcat时,如果war包没包含编译后的Referaty.class,那Tomcat自然找不到这个类。你可以:
- 打开target目录下生成的war包,解压后检查
WEB-INF/classes/com/example/model/路径下有没有Referaty.class; - 如果没有,检查Maven的打包配置,确保实体类所在的模块被正确依赖,或者
pom.xml里的compile插件没有排除这个类。
4. @OneToMany注解缺失targetEntity属性(泛型擦除场景)
如果Wydzialy类中的referaties字段没有使用泛型(比如写成private List referaties;),或者因为某些原因泛型信息被擦除了,Hibernate就没法自动识别关联的实体类。这时候需要显式指定targetEntity属性:
@OneToMany(mappedBy = "wydzialy", targetEntity = Referaty.class) private List<Referaty> referaties;
不过Hibernate Tools生成的代码一般会带泛型,但如果是旧版本工具或者生成时参数有误,也可能出现这种情况,补上这个属性就能解决。
5. 映射配置重复或冲突
如果你同时用了hibernate.cfg.xml的<mapping>配置和Spring的包扫描,偶尔会出现配置冲突导致Hibernate无法正确识别实体。这种情况概率不高,但可以检查一下,确保两种配置方式不要重复覆盖,或者路径都正确。
建议你先从检查Referaty的@Entity注解和Hibernate的扫描配置开始,这两个是最常见的触发这个异常的原因。
内容的提问来源于stack exchange,提问作者John Doe

