com.something.SuperClass:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class SuperClass implements Serializable {
private static final long serialVersionUID = -695503064509648117L;
long confirmationCode;
@Id
@GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!!
public long getConfirmationCode() {
return confirmationCode;
}
public void setConfirmationCode(long confirmationCode) {
this.confirmationCode = confirmationCode;
}
}
com.something.SubClass:
@Entity
public abstract class Subclass extends SuperClass {
private static final long serialVersionUID = 8623159397061057722L;
String name;
@Column(nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
给我这个例外:
Caused by: org.hibernate.MappingException: Cannot use identity column key
generation with <union-subclass> mapping for: com.something.SuperClass
生成ID的最佳和最方便的方法是什么? 我不想改变我的继承策略。
答案 0 :(得分:206)
这里的问题是你混合了“每个类的表”继承和GenerationType.Auto
。
考虑MsSQL中的标识列。它是基于列的。在“每类表”策略中,每个类使用一个表,每个表都有一个ID。
尝试:
@GeneratedValue(strategy = GenerationType.TABLE)
答案 1 :(得分:8)
我想知道这是否是数据库方言特定的问题,因为观看一个使用PostgreSQL作为底层数据库的youtube教程,我看到视频的创建者成功运行了一个具有默认@GeneratedValue的应用程序。在我的情况下(底层数据库是MySQL)我必须完全按照zoidbeck的建议将@GeneratedValue策略修改为GenerationType.TABLE。
答案 2 :(得分:2)
在我们的例子中,我们使用PostreSQL数据库进行开发和生产,并使用内存中的hsqldb数据库进行测试。我们在两种情况下都使用序列来生成id。显然GenerationType.AUTO
对于postgres默认为SEQUENCE
,但在我们的本地测试中失败(必须默认为hsqldb的其他内容)。
因此,适用于我们的解决方案明确使用GenerationType.SEQUENCE
。
答案 3 :(得分:2)
同意zoidbeck的回答。 您需要将策略更改为:
@GeneratedValue(strategy = GenerationType.TABLE)
但这不是全部,你需要创建一个新表,什么将保存你的抽象表主键序列。将映射修改为
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator")
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator")
public long getConfirmationCode() {
return confirmationCode;
}
数据库中的新表应如下所示:
当您运行应用程序时,Hibernate将插入一行,其中sequence_name
将是实体名称(在此示例中为SuperClass
),sequence_next_hi_value
值将自动递增并用于新所有实现子类表的记录。
答案 4 :(得分:1)
您可以使用@MappedSuperclass进行继承
答案 5 :(得分:0)
MySQL和PostgreSQL之间存在SQL标准合规性。 的PostgreSQL 的 Postgres理解SQL92 / 99的一个很好的子集以及这些子集的一些面向对象的特性。 Postgres能够处理复杂的例程和规则,如声明性SQL查询,子查询,视图,多用户支持,事务,查询优化,继承和数组。不支持跨不同数据库选择数据。
的MySQL 的 MySQL使用SQL92作为基础。在无数平台上运行。 Mysql可以构造可以连接来自不同数据库的表的查询。使用ANSI和ODBC语法支持左外连接和右外连接。从MySQL 4.1开始,MySQL将处理子查询。截至第5版支持的视图。
有关详细说明,请访问。 http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html