Вставка записи в базу данных через JPA - PullRequest
4 голосов
/ 24 апреля 2010

В моем коде я использую JSF - интерфейс, EJB-Middile Tier и JPA подключаются к DB. Вызов EJB с использованием Webservices. Использование MySQL в качестве DAtabase. Я создал таблицу избирателей, в которую мне нужно вставить запись. Я передал значения из JSF в EJB, он работает. Я создал класс контроллера JPA (который автоматически генерирует код постоянства на основе классов базы данных) Пример: получение менеджера организации и т. Д.,

    em = getEntityManager();
    em.getTransaction().begin();
    em.persist(voter);
    em.getTransaction().commit();

Я также создал именованный запрос:

@NamedQuery(name = "Voter.insertRecord", query = "INSERT INTO Voter v 
values v.voterID = :voterID,v.password = :password,v.partSSN = :partSSN,
v.address = :address, v.zipCode = :zipCode,v.ssn = :ssn, 
v.vFirstName = :vFirstName,v.vLastName = :vLastName,v.dob = :dob"),

Но все еще не можете вставить запись?

Может ли кто-нибудь помочь мне вставить запись в базу данных через JPA (объект постоянства)?

Обновление:

Если мы используем диспетчер управляемых сущностей контейнеров, нужно ли нам снова начинать и фиксировать транзакции ... как это:

em.getTransaction().begin(); 
em.getTransaction().commit(); 

Я написал:

Voter v= new Voter(voterID,password,partSSN,address,zipCode,ssn,vFirstName,vLastName,d1,voterFlag);
em.persist(v);

Но это приводит к исключению нулевого указателя.

SEVERE: java.lang.NullPointerException
    at ejb.Registration.reg(Registration.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:4038)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5223)

Ответы [ 5 ]

24 голосов
/ 24 апреля 2010

Я думаю, что вы упустили пункт JPA. С JPA вы не должны писать запросы для вставки, обновления или удаления постоянных объектов, JPA сгенерирует их для вас. Итак, что вам нужно сделать, это создать объекты домена и аннотировать их, чтобы сделать их «постоянными» (такие аннотированные объекты называются объектами) и сообщить движку JPA, как «сопоставить» их с вашей базой данных. Позвольте мне попытаться показать вам правильный путь ...

Сначала создайте объект домена Voter и добавьте аннотации JPA (класс сущности должен быть аннотирован аннотацией Entity, должен иметь конструктор без аргументов, должен реализовывать Serializable, должен быть указан первичный ключ по аннотации Id:

@Entity
public class Voter implements Serializable {
    private Long id;
    private String firstName;
    private String lastName;
    private String password;
    // other attributes

    // No-arg constructor
    public Voter() {}

    @Id @GeneratedValue // property access is used
    public Long getId()  { return this.id; }
    protected void setId(Long id)  { this.id = id; }

    // other getters, setters, equals, hashCode
}

Я здесь использую значения по умолчанию JPA (имя таблицы по умолчанию, имя столбца и т. Д.). Но это можно настроить с помощью аннотаций Table или Column, если вам нужно сопоставить вашу сущность с существующей моделью.

Затем создайте новый экземпляр и установите различные атрибуты:

Voter voter = new Voter();
voter.setFirstName(firstName);
voter.setLastName(lastName);
...

И сохраните это:

em.getTransaction().begin();
em.persist(voter);
em.getTransaction().commit();

Это всего лишь краткое введение, JPA не может быть охвачено одним ответом. Чтобы пойти дальше, я предлагаю проверить Введение в Java Persistence API из Учебного руководства по Java EE 5.

Обновление: В управляемом компоненте, например EJB, EntityManager обычно внедряется, а транзакции управляются контейнером (т. Е. Вы явно не вызываете begin/commit). В вашем случае моя ставка заключается в том, что EntityManager не был успешно введен, и вызов любого метода приводит к NPE. Но это только предположение, вам нужно предоставить больше деталей. Какая линия 39 вашего EJB? Как аннотируется EntityManager? Как выглядит ваш persistence.xml? Пожалуйста, обновите ваш вопрос с соответствующей информацией.

2 голосов
/ 26 июня 2010

Кроме того, вам не нужно снова писать и фиксировать транзакции. Как это:

em.getTransaction().begin(); em.getTransaction().commit();

только если вы используете управляемые контейнером Entity Manager, потому что это автоматически выполняется контейнером.

1 голос
/ 07 ноября 2014

если вы используете диспетчер сущностей, это означает, что вы обрабатываете транзакции с JTA, поэтому диспетчер сущностей будет обрабатываться контейнером, вы не сможете использовать

 em.getTransaction().begin();
 em.getTransaction().commit();

em.getTransaction() это транзакция объекта, которая будет обрабатываться JTA.

Вам нужно будет напрямую использовать persist(), так как у вас есть менеджер сущностей, и ваши данные будут добавлены.

Если вы хотите использовать запрос, это всегда возможно в en.createQuery ... Но я не знаю, можно ли его использовать в качестве именованного запроса.

1 голос
/ 28 января 2012

Паскаль прав, вы можете сделать это таким образом. Если вы хотите использовать именованные запросы, вы можете сделать это так:

Напишите метод, который принимает значение (я), которое нужно установить, и используйте его.

Query q  = em.createNamedQuery("NamedQueryXYZ").setParameter("parameter name", valueToSet)

Имя параметра будет использовать ваш пример «пароль» или «атрибут» в основном независимо от двоеточия.

Я довольно новичок в JPA, JSF и прочем джазе, но я надеюсь, что это поможет.

1 голос
/ 26 июня 2010

Я полагаю, что он не извлекает значения из параметров, вставленных в конструктор, что приводит к исключению NullPointerExpception. Лучше, если вы используете voter.setPassword (пароль); например, чтобы передать значения в сущность избирателя. Также проверьте, являются ли значения пустыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...