Hibernate中直接映射复合类型子属性并在JoinColumn中使用的正确语法求助
Hibernate中直接映射复合类型子属性并在JoinColumn中使用的正确语法求助
嘿,我完全懂你碰到的这个问题!之前用@Struct把PostgreSQL的复合类型cust_type映射到CustType类,在MyTable里用CustType attr是正常的,但想直接跳过中间类用attr.foo映射字段或者做关联,确实踩了坑对吧?我来给你拆解两种场景的解决办法:
一、直接把复合类型的子属性映射到实体字段
你之前试的@Column(name = "attr.foo")行不通,是因为Hibernate默认不会识别这种点语法来解析复合类型的子属性。这里最稳妥的方式是用@Embedded配合@AttributeOverride注解,明确指定子属性对应的数据库列:
// 先确保你的CustType类已经加了@Embeddable(或者保留@Struct,Hibernate里@Struct和@Embeddable兼容,用来映射SQL复合类型) @Embeddable @Struct(name = "cust_type", attributes = {"foo", "bar"}) class CustType { String foo; String bar; } // 然后在MyTable里这样映射单独的foo: class MyTable { // 如果只需要映射foo,用@AttributeOverride指定对应列 @Embedded @AttributeOverrides({ @AttributeOverride(name = "foo", column = @Column(name = "attr.foo")) }) CustType fooWrapper; // 这个字段只是用来承载foo的映射,业务里可以只取它的foo属性 // 要是你用的是Hibernate 6及以上版本,还有更简洁的方式,直接指定列名就行: @Column(name = "attr.foo") String foo; // 这种方式下Hibernate能自动解析复合类型的子列,不用额外的包装类 }
二、用复合类型子属性作为@JoinColumn的关联键
这种情况@JoinColumn确实不好使,因为它只能指向普通数据库列,这里得换成Hibernate的@JoinFormula注解,它支持用自定义SQL表达式来指定关联字段:
class MyTable { @ManyToOne @JoinFormula( value = "(attr.foo)", // 这里直接写复合类型子属性的SQL引用方式 referencedColumnName = "foo_in_my_other_entity" ) OtherEntity aaa; }
@JoinFormula会把括号里的表达式当作关联的外键来处理,只要你数据库里attr.foo和other_entity.foo_in_my_other_entity的类型匹配,就能正常建立关联。
另外提一句,要是你用的是Hibernate 5.x版本,记得在配置里指定正确的PostgreSQL方言(比如org.hibernate.dialect.PostgreSQLDialect或者对应的版本方言),这样Hibernate才能正确识别复合类型的结构。
总结一下:
- 直接映射子属性:优先用
@Embedded+@AttributeOverride,Hibernate 6+可以直接用@Column(name = "attr.foo") - 关联子属性:用
@JoinFormula替代@JoinColumn
内容来源于stack exchange
相关产品推荐
相关产品推荐

