Почему JPA persist () не генерирует первичный идентификатор с автоматическим приращением? - PullRequest
7 голосов
/ 02 февраля 2011

Я использую JPA toplink-essential и SQL Server 2008

Моя цель - получить значение первичного ключа с автоинкрементом данных, которые будут вставлены в таблицу. Я знаю, что в JDBC есть метод, похожий на getInsertedId (), который дает идентификатор первичного идентификатора с автоматическим приращением (но это после выполнения оператора вставки)

В JPA я обнаружил, что @GenratedValue annotation может добиться цели.

@Entity
@Table(name = "tableOne")
public class TableOne implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "tableId")
    private Integer tableId;

Теперь, если я запускаю приведенный ниже код, он должен дать мне автоматически увеличенный идентификатор , но он возвращает NULL ...

 EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();
 EntityTransaction txn = em.getTransaction();
 txn.begin();

 TableOne parent = new TableOne();
 em.persist(parent); //here I assume that id is pre-generated for me.
 System.out.println(parent.getTableId()); //this returns NULL :(

Ответы [ 3 ]

11 голосов
/ 02 февраля 2011

Проблема в том, что вы используете генерацию идентификатора IDENTITY.Генерация идентификатора IDENTITY не может выполнить предварительное распределение, так как для этого требуется INSERT.Генерация идентификаторов TABLE и SEQUENCE поддерживает предварительное распределение, и я бы всегда рекомендовал использовать их, и никогда не использовать IDENTITY из-за этой проблемы и из-за производительности.

Вы можете инициировать создание идентификатора при использовании генерации IDENTITY свызов флеш ().

6 голосов
/ 18 июля 2012

просто сделайте это:

public void create(T entity) {
   getEntityManager().persist(entity);
   getEntityManager().flush();
   getEntityManager().refresh(entity);
}

После обновления сущности у вас будет поле идентификатора с правильным значением.

2 голосов
/ 02 февраля 2011

Мы также используем SQL Server 2008, и он никогда не работал для меня, поэтому я всегда выполняю отдельный запрос "SELECT @@IDENTY", чтобы получить вставленный идентификатор.

Причина, по которой я обнаружил в сети, была то, что автоИдентификатор (IDENTITY) управляется базой данных и никогда не извлекается в Entity до тех пор, пока вы не зафиксируете строку или не извлечете информацию из базы данных вручную.

...