Hibernate hbm.xml映射配置 旧版Hibernate XML映射写法

1次阅读

hbm.xml文件须与实体类同包且命名一致,如com.example.user类对应user.hbm.xml;class标签name需全限定名、table指定表名;id generator需按数据库选策略;Property type影响jdbc绑定。

Hibernate hbm.xml映射配置 旧版Hibernate XML映射写法

hbm.xml 文件必须和实体类同包且命名一致

旧版 hibernatehbm.xml 做映射,不是随便放哪都行。它得和对应实体类在同一个包路径下,文件名也得严格匹配:比如类是 com.example.User,那 XML 就得叫 User.hbm.xml,放在 src/main/Resources/com/example/(或 classpath 对应位置)。

常见错误现象:org.hibernate.MappingNotFoundException: resource: User.hbm.xml not found,八成是路径或名字差了半个字符;ide 里看着在同目录,但编译后没进 classes,也常导致这个错。

  • 检查 build.gradlepom.xml 是否把 *.hbm.xml 纳入资源拷贝(maven 默认不处理非 .xml 在 resources 下的文件?错——它会,但如果你放 src/java 里就真不会)
  • 用 IDE 的 “Show in Explorer” 确认编译后 XML 确实出现在 target/classes 对应路径
  • 别用中文或空格命名文件,User Info.hbm.xml 这种直接报解析失败

标签里的 name 和 table 属性不能省略

<class></class> 是根映射元素,name 必须写全限定类名(如 com.example.User),table 得写数据库表名(如 user_info)。漏掉 name 会导致 Hibernate 根本不知道映射到谁;漏 table 则默认用类名小写当表名(user),跟实际不符就查不到数据。

使用场景:老系统表名带下划线、类名用驼峰,比如数据库是 order_item,类叫 OrderItem,那就得显式写 table="order_item",不能指望 Hibernate 自动转换。

  • schemacatalog 属性按需加,跨 schema 查询时缺一不可
  • dynamic-insert="true"dynamic-update="true" 可减少 sql 冗余字段,但会让日志更难读,调试期建议关掉
  • 别在 <class></class> 里写 lazy="false" —— 这属性只对关联映射(<many-to-one></many-to-one> 等)有效,放这儿会被忽略

id 映射必须配 ,native 不等于 auto

旧版里 <id></id> 下的 <generator class="native"></generator> 是最常用写法,但它不是“自动选”,而是按方言动态选策略:mysqlidentityoraclesequence,HSQLDB 用 identity。如果数据库不支持对应策略(比如 Oracle 没建 sequence),启动就抛 IdentifierGenerationException

性能影响:用 increment 看似简单,但在集群或高并发下会生成重复 ID,绝对别在线上用;uuid 虽安全,但字符串主键影响索引效率,且 MySQL 里 char(32)BIGINT 慢不少。

  • 明确用 identity 前,先确认数据库是否支持自增(postgresql 要用 serial 配合 identity
  • Oracle 必须配 <param name="sequence">SEQ_USER,否则 fallback 到 hilo,可能产生间隙 ID
  • <generator class="assigned"></generator> 表示手动赋值,此时代码里必须显式设 ID,否则插入时报空值

property 映射的 type 属性常被忽略但很关键

<property></property>type 不只是类型提示,它决定 Hibernate 怎么做 JDBC 绑定和结果集读取。比如 Java 的 java.time.LocalDate,不写 type="localDate"(Hibernate 5+)或 type="date"(旧版),就会当成 java.util.Date 处理,查出来时秒数乱套,甚至抛 ClassCastException

兼容性影响:Hibernate 3.x 默认不识别 JSR-310 类型,必须用第三方方言(如 hibernate-types)或自己写 UserType;而 type="yes_no" 这种内置类型,能把布尔值存成 'Y'/'N' 字符,比 bit 更兼容老数据库。

  • 字符串字段加 Length="50",不然默认长度是 255,可能触发 MySQL 的 sql_mode=STRICT_TRANS_TABLES 报错
  • not-NULL="true" 只影响 DDL 生成(create-table),不影响运行时校验,别以为加了它就能防空插入
  • access="field" 表示跳过 getter/setter 直接读写字段,适合有复杂逻辑的 setter 场景,但字段名拼错就静默失败

XML 映射真正麻烦的不是语法,而是每个属性背后都绑着方言、驱动、JDBC 类型、甚至数据库版本。改一行 type,可能让本地跑通的代码在测试环境连不上字段。

text=ZqhQzanResources