Mou*_*ast 21 java hibernate jpa
亲爱的同志们,早上好,
这开始变得烦人 - 一件简单的事情,但几个小时的斗争,我变老了吗?
我试图使用JPA by Hibernate将两个类映射到一个表.我们的想法是在父类中只有一小部分列,在子类中只有更大/全集.没有涉及TABLE继承,只有类继承.怎么能完成?
这样做不起作用:
@Entity
@Table(name = "the_table")
class Parent implements Serializable {
}
@Entity
@Table(name = "the_table")
class Child extends Parent implements Serializable {
}
Run Code Online (Sandbox Code Playgroud)
Hibernate假定默认继承策略为InheritanceType.SINGLE_TABLE,并且默认情况下正在寻找鉴别器列 - DTYPE.但是等等 - 没有表继承,鉴别器列没有出现.
我还看了一下PolymorphismType.EXPLICIT没有任何区别.堆栈跟踪是:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'apprentice0_.DTYPE' in 'where clause'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3597)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3529)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2281)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
Run Code Online (Sandbox Code Playgroud)
是的,还有一件事:
这些@MappedSuperclass并@Embeddable没有用,因为它们不能与之结合使用@Entity- 父类必须是一个@Entity本身,因为它被用于其他地方的持久性.
JB *_*zet 20
@MappedSuperclass是必须使用的注释.如果同一个类既是映射的超类又是实体,那么只需将其拆分为两个类:
@MappedSuperclass
public class Parent {
// ...
}
@Entity
public class ParentEntity extends Parent {
// no code at all here
}
@Entity
public class Child extends Parent {
// additional fields and methods here
}
Run Code Online (Sandbox Code Playgroud)
有几种方法各有其自己的警告.
1)添加注释如下:
@DiscriminatorFormula("0")
@DiscriminatorValue("0")
class BaseClass{ }
@DiscriminatorValue("00")
class SubClass extends BaseClass{ }
Run Code Online (Sandbox Code Playgroud)
其中子类的鉴别符值必须与基类不同,但在传递给Integer.valueOf(String s)方法时也会计算为相同的值.
需要注意的是 - 如果从基类的Hibernate返回一个对象,然后再次调用子类类型时,会收到一个错误,抱怨加载的对象属于错误的类.如果先调用子类查询,则基类调用将返回子类.
2)使用数据库中的视图映射表并将其用作子类的表.事实上,它可以是任何其他类匹配列映射,因为Hibernate认为它是一个完全独立的表.
警告 - 您可能会将同一行实例化为两个不同的对象,这些对象将无法同步,并可能导致数据库更新冲突/丢失.
通过使用实体映射xml文件来覆盖所需类的DiscriminatorValue以匹配常量Discriminator'Formula'值,可以将一个类型用于会话并且可以在没有运行时风险的情况下处理,这可以传递到初始配置.
使用有限的列集创建表的视图,并将第二个类映射到该类。定义一个具有有限列集的接口,并让两个类都实现该接口。这可能会满足您大约 95% 的需求。如果需要,创建方法来定义两者之间的相等性,并能够将较大的类(通过构造函数?)转换为较小的类。
| 归档时间: |
|
| 查看次数: |
16432 次 |
| 最近记录: |