我是一个初学者,正在休眠状态下进行一些继承练习。我有两个类,一个超类和一个子类,它们都通过继承SINGLE_TABLE加入。
问题是,当我要将子类的对象持久保存到数据库时,hibernate尝试在超类的表中创建“ INSERT”。由于超类表中不存在“颜色”列,因此会产生错误“未知列“颜色”在“字段列表”中”。
我还没有在两个表之间映射关联。我应该那样做吗?我的教科书未指定。否则,我该怎么办?
SUPERCLASS:--------------------------------------------- -----------------------
@Entity
@Table(name="autos")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "pe_discriminador",
discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "a1")
public class auto implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="marca")
private String marca;
@Column(name="modelo")
private String modelo;
public auto(){
}
public auto(int id, String marca, String modelo) {
this.id = id;
this.marca = marca;
this.modelo = modelo;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMarca() {
return marca;
}
public void setMarca(String marca) {
this.marca = marca;
}
public String getModelo() {
return modelo;
}
public void setModelo(String modelo) {
this.modelo = modelo;
}
@Override
public String toString() {
return "auto{" + "id=" + id + ", marca=" + marca + ", modelo=" + modelo + '}';
}
}
SUBCLASS ----------------------------------------------------------------------
@Entity
@Table(name="autos")
@DiscriminatorValue("a2")
public class auto2 extends auto{
int id2;
public auto2() {
}
public auto2(int id2, String color, double motor, int id, String marca, String modelo) {
this.id2=id2;
this.color=color;
this.motor=motor;
setMarca(marca);
setModelo(modelo);
}
@Column(name="color")
private String color;
@Column(name="motor")
private double motor;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getMotor() {
return motor;
}
public void setMotor(double motor) {
this.motor = motor;
}
@Override
public String toString() {
return "auto2{" + ", color=" + color + ", motor=" + motor + '}';
}
}
休眠错误日志:------------------------------------------- ---------------
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
oct 21, 2018 10:22:51 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
oct 21, 2018 10:22:52 AM org.hibernate.cfg.AnnotationBinder bindClass
WARN: HHH000139: Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy: entidades.auto2
Hibernate: insert into autos (marca, modelo, color, id2, motor, pe_discriminador) values (?, ?, ?, ?, ?, 'a2')
oct 21, 2018 10:22:54 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1054, SQLState: 42S22
oct 21, 2018 10:22:54 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Unknown column 'color' in 'field list'
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178)
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3072)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3663)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:359)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:131)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:709)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:696)
at testeo.TestAuto.main(TestAuto.java:225)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'color' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3978)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3914)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2495)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1903)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2124)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2058)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5158)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2043)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)
... 22 more
答案 0 :(得分:2)
0)前传答案
在进入答案之前,我想指出一点:示例代码看起来有些混乱。例如,缩进可能更直观,并且通常在PascalCase
中命名类(即camelCase
的首字母大写)。那里有许多样式指南可以为您提供帮助(例如,通过Google)。相信我:它使编码更加有趣!
1)实际答案
有多种策略可使用hibernate保存类层次结构:
您选择了SINGLE_TABLE
继承策略。这意味着,属于该层次结构的所有类和子类将被持久化到一个表(table per class hierarchy)中。
从对错误的描述来看,您的数据库架构似乎适合不同的策略。
a)每班策略表
如果有,每个具体子类一个表(这意味着:抽象超类没有表),请尝试:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Auto {
b)加入策略
如果抽象超类和您的具体子类都具有一个表,请继续:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Auto{
@Id
private int id;
// getters, setters, ...
}
@Entity
@PrimaryKeyJoinColumn(name = "id")
public class RaceAuto extends Auto {
// ...
}
在两种情况下,您都不需要区分符列。如果要使用注释,Hibernate documentation可能会引起误解。我发现这个blog post很有帮助。