【问题标题】:EJB Project doesn't connect to the right Derby database/tableEJB 项目未连接到正确的 Derby 数据库/表
【发布时间】:2014-02-25 14:26:42
【问题描述】:

昨天遇到一个问题,我无法连接到 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 existUnknown entity bean class: class model.Userbay, please verify that this class has been marked with the @Entity annotation. 之类的一堆错误

虽然现在一切都很好,但我意识到情况并非如此。起初我试图通过实体管理器的 .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>

用户注册会话Bean

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 实体 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;
    }

}

【问题讨论】:

  • 这个插入后有什么异常吗?如果你使用 JPA,如果你真的不需要它,尽量不要使用原生查询。
  • 第一次插入没有任何问题,但第二次尝试出现以下异常(因此现在将其注释掉) - org.apache.derby.client.am.SqlException: The statement被中止,因为它会导致在“USERBAY”上定义的“SQL140225111513480”标识的唯一或主键约束或唯一索引中出现重复键值。附言它仅用于测试目的,让我意识到我绝对不是在处理我期望的表。
  • 所以可能 id 的生成不起作用。尝试从数据库中删除该行并再次执行它。如果一切正常,并且仅在第二次插入时出现问题,则表示生成 ID 有问题。然后尝试更改 generateValue 策略。
  • 我不确定你是否理解我的问题。困扰我的问题是没有插入。问题是我有一个包含已经包含记录的 Userbay 表的数据库,当我尝试查找具有确实存在的主键的行时,它只返回一个空对象。东西的插入只是一个测试用例,看看它是否会被插入到 Userbay 表中(不幸的是不是)。我什至不知道数据被插入到哪个表中,因为我无法在 Eclipse - 任何 SCHEME 下的数据源资源管理器中直观地看到它。
  • 所以你不能在开始时得到任何结果(表有一些行),但是如果你插入一些数据就可以获得结果。是对的吗?我建议检查您是否在相同的数据库架构上进行操作。顺便说一句,插入语句中有 ADRIAN.USERBAY,查找查询中有 USERBAY。

标签: java ejb derby persistence.xml entity-bean


【解决方案1】:

我注意到数据库中没有插入任何内容...但是尝试执行 .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);

只要您选择生成用户名,它将为您生成。

以防万一: 请记住,即使您没有打开任何事务,容器也会在您调用 registerUser 方法时为您打开一个。这意味着您正在同一个事务中工作,直到该方法以它所暗示的所有内容结束。以下是 Oracle 教程的摘录

Required 属性是使用容器管理的事务划分运行的所有企业 bean 方法的隐式事务属性。除非您需要覆盖另一个事务属性,否则您通常不会设置Required 属性。由于事务属性是声明性的,您可以在以后轻松更改它们。

您可能需要至少阅读这些部分以更好地理解。

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

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

【讨论】:

  • 对不起,我的解释很糟糕,我在“没有任何东西插入数据库”中的意思是在我的模式 ADRIAN - Userbay 表下没有插入任何东西。它也没有插入到数据库中存在的任何其他模式中。说我可以检索插入的值 testts123s,这是真的,因为在我插入“testts123s”之前我正在处理一个空表。因此我的假设是创建了一个新表,它没有与我想要的数据库链接,结论是我不知道我正在处理什么架构/数据库。
【解决方案2】:

在搞砸了persistence.xml 几天后,我幸运地找到了一个oracle 教程,该教程指导为glassfish 服务器创建新的JDBC 连接池和资源,以链接derby 数据库。完成后,我需要在 persistence.xml 中放入 JTA 数据源。

这是我从头开始制作的视频,这次选择了 ClientDriver - http://www.youtube.com/watch?v=xBNB8L49ZQ4

【讨论】:

    猜你喜欢
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    相关资源
    最近更新 更多