EJB Project не подключается к нужной базе данных / таблице Derby

Вчера у меня возникла проблема, связанная с тем, что я не смог подключиться к базе данных derby (скорее всего, из-за проблем с persistence.xml). Я получил указание изменить свой файл persistence.xml, чтобы он содержал две дополнительные функции;

<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />

Добавив их, я не сталкиваюсь с кучей ошибок, таких как SCHEMA "xx" doesn't exist или же Unknown entity bean class: class model.Userbay, please verify that this class has been marked with the @Entity annotation.

Хотя теперь все будет хорошо, я понял, что это не так. Сначала я пытался получить одну из строк в базе данных с помощью метода Entity Manager.find(). После некоторого времени тестирования для извлечения записей из базы данных я подумал, что может быть лучше попытаться вставить что-то в базу данных и посмотреть, что произойдет. Выполнив следующую строку кода;

emgr.createNativeQuery("insert into ADRIAN.USERBAY (USER_NAME, PASSWORD, EMAIL, FIRST_NAME, LAST_NAME) values('testts123s', '1', '1', '1', '1')").executeUpdate();

Я заметил, что ничего не было вставлено в базу данных... Однако, попытавшись выполнить.find(), чтобы найти только что вставленный первичный ключ (testts123s), он нашел запись (хотя в проводнике источников данных таблица базы данных не не заполняется этой записью). Поэтому мои вопросы: что могло произойти, если бы я был связан с пустой таблицей?

Ниже приведен код;

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="EJBAuctionv2">
    <!-- <jta-data-source>JDBC/MyDB</jta-data-source> -->
        <class>model.Userbay</class>
        <class>model.Item</class>
        <class>model.Category</class>

        <properties>
     <property name="javax.persistence.jdbc.password" value="123" />
     <property name="javax.persistence.jdbc.user" value="adrian" />
     <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeededDriver" />
     <property name="javax.persistence.jdbc.url" value="jdbc:derby:C:\Users\Adrian\MyDB;create=true" />
<!-- <property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />  -->
    </properties>
    </persistence-unit>
</persistence>

UserRegistration SessionBean

package auction;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Remote;
import javax.ejb.Singleton;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.management.Query;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import model.Userbay;

/**
 * Session Bean implementation class userRegistrationSB
 */
@Remote @Stateless
public class userRegistrationSB implements userRegistrationSBRemote {

    //@EJB private Userbay user;
    @PersistenceContext(name = "EJBAuctionv2") private EntityManager emgr;
    /**
     * Default constructor. 
     */
    public userRegistrationSB() {}

    @Override
    public boolean registerUser(String username, String password, String email,
            String firstname, String lastname) {
        boolean registered = false;

        //emgr.createNativeQuery("insert into ADRIAN.USERBAY (USER_NAME, PASSWORD, EMAIL, FIRST_NAME, LAST_NAME) values('testts123s', '1', '1', '1', '1')").executeUpdate();

        System.out.println("Registering an user with username: " + username);
        Userbay user = emgr.find(model.Userbay.class, username);
        if (user == null) {
            System.out.println("Username doesn't exist.");
            registered = true;
        } else {
            registered = false;
            System.out.println("Username already exists.");
        }

        return registered;
    }

    @Override
    public boolean userExists(String username) {
        return false;
    }

    @Override
    public boolean userMatchesPassword(String username, String password) {
        return false;
    }

}

Userbay Entity Bean

package model;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;




@Entity @Table (name = "Userbay")
@NamedQuery(name="Userbay.findAll", query="SELECT u FROM Userbay u")
public class Userbay implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue (strategy = GenerationType.TABLE)
    @Column(name="USER_NAME")
    private String userName;

    private String email;

    @Column(name="FIRST_NAME")
    private String firstName;

    @Column(name="LAST_NAME")
    private String lastName;

    @Column(name="PASSWORD")
    private String password;

    //bi-directional many-to-one association to Item
    @OneToMany(mappedBy="userbay")
    private List<Item> items;

    public Userbay() {
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<Item> getItems() {
        return this.items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public Item addItem(Item item) {
        getItems().add(item);
        item.setUserbay(this);

        return item;
    }

    public Item removeItem(Item item) {
        getItems().remove(item);
        item.setUserbay(null);

        return item;
    }

}

2 ответа

Решение

После нескольких дней работы с persistence.xml я, к счастью, нашел руководство по оракулу, которое поможет создать новый пул соединений JDBC и ресурс для сервера Glassfish, чтобы связать базу данных derby. После этого все, что мне нужно было поместить в файл persistence.xml, - это источник данных JTA.

Вот видео, где я сделал это с нуля, на этот раз выбирая ClientDriver - http://www.youtube.com/watch?v=xBNB8L49ZQ4

Я заметил, что в базу данных ничего не вставлено... Однако, попытавшись выполнить.find(), чтобы найти только что вставленный первичный ключ (testts123s), он нашел запись.

Как именно вы заметили, что ничего не было вставлено в базу данных? Читая ваше следующее предложение, похоже, это было.

Несмотря на

Вы должны избегать вставки записей с собственным SQL. Прежде всего, делая это, вы обходите кеш, и это может принести вам настоящую головную боль и, наконец, разрушить всю идею ORM. Таким образом, вместо этого вам лучше сделать это с помощью постоянного метода управления сущностями.

Userbay user = new Userbay();
user.setFirstName("Firstname");
user.setLastName("Lastname");
user.setPassword("password");
user.setEmail("someemail@email.zzz");

emgr.persist(user);

Насколько вы решили создать userName, он будет создан для вас.

На всякий случай: имейте в виду, что даже если вы не открывали какую-либо транзакцию, контейнер открыл ее для вас, когда вы вызывали метод registerUser. Это означает, что вы работаете в одной транзакции, пока метод не завершится со всеми вытекающими последствиями. Ниже приведено извлечение из учебника Oracle

Атрибут Required является неявным атрибутом транзакции для всех методов корпоративного компонента, работающих с разграничением транзакций, управляемым контейнером. Обычно вы не устанавливаете атрибут Required, если вам не нужно переопределять другой атрибут транзакции. Поскольку атрибуты транзакции являются декларативными, вы можете легко изменить их позже.

Вы можете прочитать хотя бы эти разделы для лучшего понимания.

http://docs.oracle.com/javaee/6/tutorial/doc/bnbpy.html

http://docs.oracle.com/javaee/6/tutorial/doc/bncih.html

Другие вопросы по тегам