2015-10-12 2 views
0

У меня есть юридическое лицоJPA @SequenceGenerator с ручным ID и 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) 
) 

То, что я хочу достичь, это когда-нибудь я хотел бы использовать последовательность/идентификатор генерируется базой данных , но когда-то данные создаются в другом месте, и я хотел бы создать с существующим (ручным) id.

Я не могу установить идентификатор вручную с помощью метода Spring Data JPA (с использованием CrudRepository) или JPA способом (с использованием EntityManager), но не проблема с собственным запросом. Это ограничение 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.

+1

I * думаю * это может быть как работает '@ GeneratedValue' jpa (я не уверен). Однако это не имеет значения, потому что если вы хотите смешивать созданные идентификаторы с вставленными вручную, последовательность [не будет лучшим выбором] (http://www.postgresql.org/message-id/[email protected] nyroc.rr.com) (ни любое решение 'int' /' bigint'). Вы должны рассмотреть возможность использования чего-то совершенно другого, f.ex. 'uuid's. – pozs

ответ

0

Да, по умолчанию Hibernate org.hibernate.id.SequenceGenerator всегда генерирует новый идентификатор. То, что вы должны сделать, это переопределить метод public Serializable generate(SessionImplementor session, Object obj), где, если ваш obj (отнесенный к вашей сущности первым) имеет идентификатор, а затем возвращает идентификатор, а затем получить его из последовательности базы данных.

0

На проходят, если поле помечается @GeneratedValue, он будет генерировать идентификатор с любой стратегией указан. Затем он установит значение поля id с генерируемым значением. Поэтому, если идентификатор вручную устанавливается с помощью setId() перед сохранением, это будет просто завышено.

Если вы хотите, вы можете использовать em.persist для автогенерированных идентификаторов. Затем используйте собственный SQL для ручной установки идентификатора, поскольку собственные SQL-запросы будут обходить любое сопоставление, имеющееся на вашем объекте.