Hibernate 从第三方库映射值对象
我需要通过Hibernate注释将以下实体持久化到关系数据库:Hibernate 从第三方库映射值对象,hibernate,jpa,Hibernate,Jpa,我需要通过Hibernate注释将以下实体持久化到关系数据库: @Entity @Table(name="fizzes") public class Fizz { @Id @GeneratedValue @Column(name="fizz_id") private int id; @Column(name="fizz_wooz") private String wooz; // ??? here I am unsure! privat
@Entity
@Table(name="fizzes")
public class Fizz {
@Id @GeneratedValue
@Column(name="fizz_id")
private int id;
@Column(name="fizz_wooz")
private String wooz;
// ??? here I am unsure!
private Buzz buzz;
// Constructor, getters/setters down here, etc...
}
public class Buzz {
private int jupiter;
private String neptune;
// Constructor, getters/setters down here, etc...
}
Buzz
的问题是:
- 我不希望它成为自己的实体/表。我希望它是一个映射到
表的“值对象/类型”(通过向其添加列)fizzes
来自第三方库,因此我无法修改它Buzz
[fizzes] table
==============
fizz_id, PRIMARY KEY AUTO INCREMENT
fizz_wooz, NVARCHAR(50) NOT NULL
fizz_buzz_jupiter, INT NOT NULL
fizz_buzz_neptune, NVARCHAR(100) NOT NULL
当我无法修改
Buzz
时,如何让Hibernate进行这种基于注释的映射?我想您希望Buzz
对象的属性出现在Fizz
对象中,这意味着Buzz
和Fizz
的属性都应该作为列出现在同一个表中fizzes
因此,您必须扩展Fizz
对象,其中Buzz
将被注释为@MappedSuperClass
@Entity
@Table(name="fizzes")
public class Fizz extends Buzz {
// Fizz properties
// No need to add Buzz as a field
}
@MappedSuperclass
public class Buzz {
// Buzz properties
}
如果不添加
@MappedSuperclass
注释,则无法实现此目的。即使Buzz
被Fizz
扩展,Hibernate也不会识别Buzz
的字段,因为Hibernate只反映Fizz
中的字段,而不会反映在extendedBuzz
类中的字段上,除非您指定@MappedSuperclass
注释。MappedSuperclass将告诉hibernate在Buzz
对象的字段上也使用反射 您正在搜索的是可嵌入的
@Entity
public class Fizz {
...
@Embedded
private Buzz buzz;
}
您可以仅为Buzz
定义映射文件:
<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
<embeddable class="...Buzz">
<attributes>
<basic name="jupiter"><column name="fizz_buzz_jupiter"/></basic>
<basic name="neptune"><column name="fizz_buzz_neptune"/></basic>
</attributes>
</embeddable>
</entity-mappings>
如果您确实想为Buzz
使用注释:您不能为其他类定义注释。这就是注释的含义:它们是内联的,属于它们的类。否则,与映射文件相比将没有任何好处
但您可以扩展Buzz,并将其与属性访问一起使用:
唯一的缺点:您不能在Fizz
中使用Buzz
的实例,谢谢@user1354678(+1)-但是,我不能修改Buzz
源代码!!!换句话说,我不能添加@MappedSuperclass
…想法?@DirtyMikeAndTheBoys,我已经更新了我的答案。没有@MappedSuperclass
注释,我没有尝试过。我想hibernate的工作方式就是我在上一篇文章中解释的。也许您尝试不使用@MappedSuperclass
注释。再次感谢@user1354678,但您真的是说Hibernate不能或/M由第三方创建/拥有的类吗?例如,如果Maven Central的某个第三方JAR包含一些我希望作为值对象/类型持久化的类,您告诉我,如果不修改它们的源代码以包含@MappedSuperclass
?!?,就无法做到这一点?!?!如果那是真的,那我就完完全全被雷了@DirtyMikeAndTheBoys,我说可以通过在父类中将第三方的字段定义为字段来将其用作子表,但如果通过在父类中扩展它来使用第三方类,则不能。正如我前面所说,我没有尝试过没有@MappedSuperclass
注释的情况,也许您可以尝试,但我假设结果不会反映该字段。看起来有了@Embedded
annotation@user1354678:您错过了可嵌入的概念。使用MappedSuperclass
将属性放在同一个表中会导致糟糕的类设计。非常感谢@Tobias Liefke(+1和绿色复选框)@是的,我没有源代码,也不想因为修改类而违反任何许可。至于为什么我需要注释而不是映射文件,我只是更喜欢注释,因为它们更干净(IMHO)。再次感谢你的帮助!
<persistence-unit>
<mapping-file>.../orm.xml</mapping-file>
</persistence-unit>
@Entity
public class Fizz {
...
@Embedded
private BuzzExtension buzz;
}
@Embeddable
@Access(AccessType.PROPERTY)
public class BuzzExtension extends Buzz {
@Column(name="fizz_buzz_jupiter")
public int getJupiter() {
return super.getJupiter();
}
@Column(name="fizz_buzz_neptune")
public String getNeptune() {
return super.getNeptune();
}
}