我们先讨论一种简单的情况,多个已知的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相关文章