Java for Web学习笔记(一零九):再谈Entity映射(2)Entity的继承

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

猜你喜欢

转载自blog.csdn.net/flowingflying/article/details/79358239