具有手动 ID 和自动 ID 的 JPA @SequenceGenerator
JPA @SequenceGenerator with Manual ID and Auto ID
我有一个实体
@Entity
public class Book {
@Id
@Column(name = "book_id")
@SequenceGenerator(name = "book_book_id_seq", sequenceName = "book_book_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_book_id_seq")
private Long id;
// getter, setter & other fields
}
有架构
CREATE TABLE book
(
book_id bigint NOT NULL DEFAULT nextval('book_book_id_seq'::regclass),
CONSTRAINT book_pkey PRIMARY KEY (book_id)
)
我想要实现的是有时我想使用数据库生成的 sequence/id,但有时数据是在其他地方创建的,我想用现有的(手动)id 创建。
我无法使用 Spring 数据 JPA 方式(使用 CrudRepository
)或 JPA 方式(使用 EntityManager
)手动设置 ID,但本机查询没有问题。这是 JPA 限制吗?我的问题有解决方法吗?
Book book01 = new Book();
bookRepo.save(book01); // Book with id 1 is created
Book book02 = new Book();
book02.setId(5555L);
bookRepo.save(book02); // Does not create book with id 5555, but 2
Query nativeQuery = entityManager.createNativeQuery("INSERT INTO book VALUES (6666);");
nativeQuery.executeUpdate(); // Book with id 6666 is created
Query nativeQuery02 = entityManager.createNativeQuery("INSERT INTO book DEFAULT VALUES;");
nativeQuery02.executeUpdate(); // Book with id 3 is created
我正在使用 PostgreSQL 9.4、Hibernate 5 和 Java 8。
持久化时,如果一个字段用@GeneratedValue 注释,它将使用指定的任何策略生成ID。然后它将使用生成的值设置 id 字段的值。因此,如果在持久化之前使用 setId() 手动设置 id,这将被覆盖。
如果需要,您可以使用 em.persist 自动生成的 ID。然后使用 native SQL 手动设置 Id,因为 native SQLs 将绕过实体上的任何映射。
是的,默认情况下 Hibernate org.hibernate.id.SequenceGenerator
总是生成新的 ID。你应该做的是重写 public Serializable generate(SessionImplementor session, Object obj)
方法,如果你的 obj
(首先投射到你的实体)有 id,那么 return 有 id,否则从数据库序列中获取它。
我有一个实体
@Entity
public class Book {
@Id
@Column(name = "book_id")
@SequenceGenerator(name = "book_book_id_seq", sequenceName = "book_book_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_book_id_seq")
private Long id;
// getter, setter & other fields
}
有架构
CREATE TABLE book
(
book_id bigint NOT NULL DEFAULT nextval('book_book_id_seq'::regclass),
CONSTRAINT book_pkey PRIMARY KEY (book_id)
)
我想要实现的是有时我想使用数据库生成的 sequence/id,但有时数据是在其他地方创建的,我想用现有的(手动)id 创建。
我无法使用 Spring 数据 JPA 方式(使用 CrudRepository
)或 JPA 方式(使用 EntityManager
)手动设置 ID,但本机查询没有问题。这是 JPA 限制吗?我的问题有解决方法吗?
Book book01 = new Book();
bookRepo.save(book01); // Book with id 1 is created
Book book02 = new Book();
book02.setId(5555L);
bookRepo.save(book02); // Does not create book with id 5555, but 2
Query nativeQuery = entityManager.createNativeQuery("INSERT INTO book VALUES (6666);");
nativeQuery.executeUpdate(); // Book with id 6666 is created
Query nativeQuery02 = entityManager.createNativeQuery("INSERT INTO book DEFAULT VALUES;");
nativeQuery02.executeUpdate(); // Book with id 3 is created
我正在使用 PostgreSQL 9.4、Hibernate 5 和 Java 8。
持久化时,如果一个字段用@GeneratedValue 注释,它将使用指定的任何策略生成ID。然后它将使用生成的值设置 id 字段的值。因此,如果在持久化之前使用 setId() 手动设置 id,这将被覆盖。
如果需要,您可以使用 em.persist 自动生成的 ID。然后使用 native SQL 手动设置 Id,因为 native SQLs 将绕过实体上的任何映射。
是的,默认情况下 Hibernate org.hibernate.id.SequenceGenerator
总是生成新的 ID。你应该做的是重写 public Serializable generate(SessionImplementor session, Object obj)
方法,如果你的 obj
(首先投射到你的实体)有 id,那么 return 有 id,否则从数据库序列中获取它。