Question

I am trying to learn JPA. If I do a write and then immediately read before calling close, it works. But if I try to read on its own, it doesn't. Here is my code in User:

@Entity
@Table(name = "JPA_Users")
public class User {

    @Id @GeneratedValue
    @Column(name = "user_id")
    private int id;

    @Column(name = "username")
    private String username;

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

    public User(){}

    public User(String username, String password){
        this.username = username;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString(){
        return Integer.toString(id) + ":" + username + ":" + password;
    }
}

And here is the JPA code:

public void write(){
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");

    EntityManager em = emf.createEntityManager();
    EntityTransaction et = em.getTransaction();
    et.begin();

    User user = new User("Chris", "123456");
    User user2 = new User("Dave", "password");
    User user3 = new User("Peter", "asfdfsdf");
    em.persist(user);
    em.persist(user2);
    em.persist(user3);
    em.flush();

    List users = em.createQuery("SELECT u FROM User u").getResultList();
    System.out.println(users.size() + " user(s) found");
    for(Object o : users){
        User u = (User) o;
        System.out.println(u.getId());
        System.out.println(u.getUsername());
        System.out.println(u.getPassword());
        System.out.println("--------------------------");
    }

    et.commit();
    em.close();     
    emf.close();
}

The above works, and prints out the user details. But if I run the below method on its own, it doesn't work. It prints out "0 user(s) found". I have checked in SQL Developer to see if the table is there and populated, and it is.

public void read(){
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");
    EntityManager em = emf.createEntityManager();
    List users = em.createQuery("SELECT u FROM User u").getResultList();
    System.out.println(users.size() + " user(s) found");
    for(Object o : users){
        User u = (User) o;
        System.out.println(u.getId());
        System.out.println(u.getUsername());
        System.out.println(u.getPassword());
        System.out.println("--------------------------");
    }
    em.close();
    emf.close();
}

This on it's own also doesn't work:

public void read(){
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");
    EntityManager em = emf.createEntityManager();
    User u = em.find(User.class, 1);
    System.out.println(u);
    em.close();
    emf.close();
}

And finally, here is persistence.xml. I don't understand most of this below so I guess the problem is something to do with what is in here. Thank you, I appreciate any help.

<persistence 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_1_0.xsd"
    version="1.0">
    <persistence-unit name="helloworld">
    <properties>
        <!-- Scan for annotated classes and Hibernate mapping XML files -->
        <property name="hibernate.archive.autodetection" value="class, hbm" />

        <!-- SQL stdout logging -->
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="use_sql_comments" value="true" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
        <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
        <property name="hibernate.connection.url"
            value="jdbc:My_Database_location" />
        <property name="hibernate.connection.username" value="My_Username" />
        <property name="hibernate.connection.password" value="My_Password"/>

        <property name="hibernate.hbm2ddl.auto" value="create" />
        <property name="hibernate.c3p0.min_size" value="2" />
        <property name="hibernate.c3p0.max_size" value="30" />
        <property name="hibernate.c3p0.timeout" value="300" />
        <property name="hibernate.c3p0.max_statements" value="50" />
        <property name="hibernate.c3p0.idle_test_period" value="3000" />
    </properties>
</persistence-unit>

Was it helpful?

Solution

 User u = em.find(User.class, 1);

and you are 100% sure that there IS in fact entity in your user table with ID =1 right?...

OTHER TIPS

EntityManagerFactory instances are heavyweight objects. It should only be created once. You should make a singleton instead of creating a new one in every read/write at least you're just going to do that operation once in the application life. Check the first code this user posted as an example, you can copy and paste it:

When should EMF instances be created and closed

The last comment has fixed it, changing "create" to "validate", thanks a lot. :)

I was just about to post:

I got rid of the @GeneratedValue and added the IDs 1, 2 and 3 myself. Then I ran it again with IDs 4, 5 and 6. And in my database, I had IDs 4, 5 and 6 - 1, 2 and 3 had just disappeared.

Changing create to validate has fixed this problem, as well as the reading problem. So again, thank you! I don't understand what create and validate do though. I'll have a google now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top