MySQL主鍵自動生成
表設計
CREATE TABLE Stock (
id BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
NO VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
price DECIMAL(6,2) NOT NULL,
UNIQUE KEY Stock_NO (NO),
INDEX Stock_Name(name)
) ENGINE = InnoDB;
JPA主鍵映射
@Entity
@Table(name = "Stock", uniqueConstraints = {
@UniqueConstraint(name = "Stock_NO", columnNames = { "NO" })
},
indexes = {
@Index(name = "Stock_Name", columnList = "name")
})
public class Stock {
private long id;
private String no;
private String name;
private double price;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@GeneratedValue(strategy = GenerationType.IDENTITY):實體主鍵生成策略是自動生成,兼容MySQL主鍵自動生成策略,關鍵詞是AUTO_INCREMENT。若是MySQL主鍵沒有指定AUTO_INCREMENT,報出以下異常。javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute statement
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
@UniqueConstraint(name = "Stock_NO", columnNames = { "NO" })
},
indexes = {
@Index(name = "Stock_Name", columnList = "name")
}:創建唯一性索引,索引名字是Stock_NO,針對列是NO,創建索引,索引名字是Stock_Name,針對列是name。只有啓動了模式生成,索引生成的配置才能生效。啓用模式生成,在配置文件persistence.xml做如下配置:
<properties>
<property name="javax.persistence.schema-generation.database.action"
value="drop-and-create" />
</properties>
模式生成雖然很方便,能自動生成表結構,但是,由它生成的表結構不總是最佳的,而且還不能保證是正確的。因此,作爲最佳實踐,不建議在生產環境啓用模式生成,手工維護表機構。禁用模式生成,在配置文件persistence.xml做如下配置: <properties>
<property name="javax.persistence.schema-generation.database.action"
value="none" />
</properties>
生成器表
MySQL生成器表
CREATE TABLE CreatorKey (
TableName VARCHAR(64) NOT NULL PRIMARY KEY,
KeyValue BIGINT UNSIGNED NOT NULL,
INDEX CreatorKey_Table_Values (TableName, KeyValue)
) ENGINE = InnoDB;
MySQL目標表
CREATE TABLE Student (
id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
INDEX Student_name (name)
) ENGINE = InnoDB;
JPA主鍵映射
@Entity
@Table
public class Student {
private long id;
private String name;
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "studentGenerator")
@TableGenerator(name = "studentGenerator", table = "creatorkey",
pkColumnName = "TableName", pkColumnValue = "Publishers",
valueColumnName = "KeyValue", initialValue = 1,
allocationSize = 1)
@Column(name = "studentId")
public long getId() {
return id;
}
name :主鍵生成策略定義的名字;table:生成器表在數據庫中的名字;pkColumnName:生成器表的主鍵列的名字;pkColumnValue:生成器表主鍵列的值;valueColumnName:生成器表值列的名字;initialValue:生成器表初始值;allocationSize:生成器表數值遞增或遞減幅度。generator:主鍵生成策略定義的名字,該屬性與name屬性保持一致;generator = "studentGenerator":使用生成器表的主鍵生成策略。主鍵@TableGenerator的屬性initialValue,allocationSize
/**
* (Optional) The initial value to be used to initialize the column
* that stores the last value generated.
*/
int initialValue() default 0;
/**
* (Optional) The amount to increment by when allocating id
* numbers from the generator.
*/
int allocationSize() default 50;
但是,根據實際測試結果,情況並非如源代碼表示的那樣。清空生成器表creatorkey、目標表student,去掉屬性initialValue、allocationSize,執行持久化操作。 Student student = new Student();
student.setName("張三");
manager.persist(student);
得到的結果卻是這樣的。主鍵@TableGenerator的範圍
/**
* Defines a primary key generator that may be
* referenced by name when a generator element is specified for
* the {@link GeneratedValue} annotation. A table generator
* may be specified on the entity class or on the primary key
* field or property. The scope of the generator name is global
* to the persistence unit (across all generator types).
但是,根據實際測試結果,情況並非如源代碼表示的那樣。即使在同一持久化單元內,@TableGenerator的主鍵生成策略定義只對定義它的實體生效。
@Entity
@Table
public class Book implements Serializable
{
private long id;
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "studentGenerator")
public long getId()
{
return this.id;
}
public void setId(long id)
{
this.id = id;
}
啓動web server,報出如下異常。javax.persistence.PersistenceException: [PersistenceUnit: EntityMappings] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.AnnotationException: Unknown Id.generator: studentGenerator
org.hibernate.AnnotationException: Unknown Id.generator: studentGenerator
若在實體Book加上對主鍵生成策略的定義,就運行正常。@Entity
@Table
public class Book implements Serializable
{
private long id;
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "studentGenerator")
@TableGenerator(name = "studentGenerator", table = "creatorkey",
pkColumnName = "TableName", pkColumnValue = "Publishers",
valueColumnName = "KeyValue", initialValue = 1, allocationSize=1)
public long getId()
{
return this.id;
}
public void setId(long id)
{
this.id = id;
}