0

I have an entity

@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
}

with schema

CREATE TABLE book
(
  book_id bigint NOT NULL DEFAULT nextval('book_book_id_seq'::regclass),
  CONSTRAINT book_pkey PRIMARY KEY (book_id)
)

What I want to achieve is sometime I would like to use sequence/id generated by database, but sometime the data is created at other place and I would like to create with existing (manual) id.

I can't set the id manually with Spring Data JPA way (using CrudRepository) or JPA way (using EntityManager), but no issue with native query. Is this JPA limitation? Any workaround for my issue?

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

I am using PostgreSQL 9.4, Hibernate 5 and Java 8.

4

2 回答 2

1

在持久化时,如果一个字段使用@GeneratedValue 进行注释,它将使用指定的任何策略生成 ID。然后它将使用生成的值设置 id 字段的值。因此,如果在持久化之前使用 setId() 手动设置 id,这将被覆盖。

如果需要,您可以使用 em.persist 自动生成 ID。然后使用本机 SQL 手动设置 Id,因为本机 SQL 将绕过您在实体上的任何映射。

于 2015-10-12T11:51:26.797 回答
0

是的,默认情况下 Hibernateorg.hibernate.id.SequenceGenerator总是生成新的 id。你应该做的是覆盖public Serializable generate(SessionImplementor session, Object obj)方法,如果你的obj(首先转换到你的实体)有id,然后返回id,否则从数据库序列中获取它。

于 2015-10-27T04:20:58.767 回答