Создание записей в базе данных с использованием JPA и автоматически сгенерированных первичных ключей - PullRequest
0 голосов
/ 21 июня 2011

Я новичок в Java EE / JPA, в настоящее время посещаю курс для начинающих по программированию в Java EE.

Я пытаюсь создать новые записи в базе данных, последовательность которой определена для генерация идентификатора, который должен использоваться в качестве первичного ключа.

Это сущность, сгенерированная Eclipse из таблицы базы данных:

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

   @Id
   @SequenceGenerator(name = "ADDR_PROJ_ID_GENERATOR", sequenceName = "ADDR_SEQ")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"ADDR_PROJ_ID_GENERATOR")
   @Column(insertable = false, updatable = false)
   private long id;

   // ...
   // other fields
}

(Кстати, long getId() реализовано, но void setId(long) нет.)

Таблица и последовательность были созданы с использованием следующих операторов SQL:

CREATE TABLE addr_proj (
    id           INTEGER PRIMARY KEY,
    name         VARCHAR(30),
    address      VARCHAR(30),
    birthday     DATE,
    email        VARCHAR(50),
    workphone    DECIMAL(4,0)
);

CREATE SEQUENCE addr_seq
START WITH 1
INCREMENT BY 1
NOMAXVALUE;

Ручные вставки в таблицу работают нормально, используя такие выражения:

INSERT INTO addr_proj VALUES
(
   addr_seq.nextval,
   'Matt',
   '3 Fake Ave, Madeuptown',
   '01-apr-1980',
   'matt@madeupemail.com',
   '1234'
);

Однако, когда я пытаюсь выполнить обновление через DAO, я получаю сообщения об ошибках вроде следующего:

Caused By: org.apache.openjpa.lib.jdbc.ReportingSQLException:
ORA-01400: cannot insert NULL into ("AJP05"."ADDR_PROJ"."ID")
{prepstmnt 28 INSERT INTO ADDR_PROJ (address, birthday, email, name,
workphone) VALUES (?, ?, ?, ?, ?) [params=(String) 43 Fake Ln, NotA
City, (Date) 1963-02-04, (String) pete@email.not, (String) Pete,
(BigDecimal) 1337]} [code=1400, state=23000]
   at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:192)
   at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$700(LoggingConnectionDecorator.java:57)
   at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:866)
   at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:269)
   at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1421)
   Truncated. see log file for complete stacktrace

Обратите внимание, что код пытается вставить 5 значений, когда требуется 6 - идентификатор отсутствует.

Код DAO выглядит (что-то) примерно так:

void add(AddrProj item) {
    em.persist(item);
}

В чем причина этой проблемы?

Нужен ли метод setId(long) в моем классе сущностей?

Нужен ли специальный код в методе DAO add() для управления генератор последовательности?

Я что-то упустил?

Примечание: это домашняя работа, но мой выбор попробовать использовать автоматически сгенерированный первичный ключ был немного за рамками назначения. Это не было рассмотрено в курсе.

1 Ответ

1 голос
/ 21 июня 2011

Удалите @Column (вставляемый = ложный, обновляемый = ложный), и столбец будет частью вставки и обновления.

Ознакомьтесь с разделом документации аннотации jpa hibernate "2.2.2.3. Объявление атрибутов столбца".

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

insertable (optional): whether or not the column will be part of the insert statement (default true)
updatable (optional): whether or not the column will be part of the update statement (default true)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...