我们先讨论一种简单的情况,多个已知的table具有相同的schema,能否映射到同一个Entity中。然后在下一学习讨论一种复杂的情况,我们在运行中可能会动态建立表格,这些表格具有相同的schema,如果使用JPA?
假设test_a,test_b和test_c表格具有相同的表格结构,即schema相同,我们不能将其映射到同一个entity中,因为每个entity类都和一个table具体映射。如果我们不想写重复的代码,可以使用继承的方式。
下面的方式同样适用于这几个表格的schema基本相似,差异将通过extends来体现。
@Inheritance: Table per class
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbsTestEntity {
@Id
private Long id;
private String name;
.....
}
如果真实存在一个Test表格,我们不需要abstract。@Inheritance表明这个Entity的schema是可以继承的。
@Entity
@Table(name="test_a")
public lass TestA extends AbsTestEntity {
}
@Entity
@Table(name="test_b")
public lass TestB extends AbsTestEntity {
private String data;
......
}
但是这种方式有一个问题,如果:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbsTestEntity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) //将导致异常
private Long id;
private String name;
.....
}
这会出现异常:
Caused by: org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: cn.wei.flowingflying.chapter22.site.entity.AbsTestEntity
at org.hibernate.persister.entity.UnionSubclassEntityPersister.<init>(UnionSubclassEntityPersister.java:82)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77)
at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:128)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:301)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:889)
... 27 more
这种方式不支持IDENTITY的生成器。需要特别注意。
@MappedSuperclass
我们的表格通过具有AUTO_INCREMENT,这导致无法使用上面的方式,这种情况,我们可以用@MappedSuperclass。
@MappedSuperclass
public abstract class AbsTestEntity {
private Long id;
private String name;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
.....
}
相关链接:
我的Professional Java for Web Applications相关文章