开发者

How do I prevent EclipseLink (JPA 2.0) from clearing my database/table?

开发者 https://www.devze.com 2023-03-06 15:52 出处:网络
I\'m using EclipseLink (JPA 2.0) on Netbeans 7.0 with a MySQL database - which I configured according to this screencast. But sometimes when I persist an Object/Entity my table get\'s cleared before t

I'm using EclipseLink (JPA 2.0) on Netbeans 7.0 with a MySQL database - which I configured according to this screencast. But sometimes when I persist an Object/Entity my table get's cleared before that object persists, and I get a table with only this object (like it has been cleared). I'm only simply adding new entries in (populating) the database.

How can I prevent this?

Here's my code:

Movie movie = new Movie(
    jsondata.path("Title").getTextValue(),
    jsondata.path("Year").getValueAsInt(),
    jsondata.path("Genre").getTextValue(),
    jsondata.path("Plot").getTextValue(),
    jsondata.path("Poster").getTextValue());
persist(movie);

My persist() function:

public static void persist(Object object) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("AllmoviesPU");
    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    try {
        em.persist(object);
        em.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
        em.getTransaction().rollback();
    }
    em.close();
}

My Movie object/entity:

@Entity
public class Movie implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    @Column(name="MOVIEYEAR")
    private int year;
    private String genre;
    private String synopsis;
    private String image;

    public Movie(String title, int ye开发者_StackOverflow中文版ar, String genre, String synopsis, String image) {
        this.title = title;
        this.year = year;
        this.genre = genre;
        this.synopsis = synopsis;
        this.image = image;
    }

    public Movie() {
    }

    /* ... Getters and Setters stuff ... */

}

My 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="AllmoviesPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>allmovies.data.Movie</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://123.123.123.123:3306/psanta_allmovies"/>
      <property name="javax.persistence.jdbc.password" value="XXXXXX"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="psanta_allmovies"/>
    </properties>
  </persistence-unit>
</persistence>


Try turning on logging to FINEST or FINE to see what is occurring. ("eclipselink.logging.level"="finest").

EclipseLink does have an option to recreate tables on startup ("eclipselink.ddl-generation"="drop-and-create-tables"), ensure you are not using that. NetBeans or Glassfish may be setting this by default, I think they may do this when in development mode.


There are bunch of things that need to be addressed in your code, although I cannot guarantee they are related to your problem.

The first thing is that creating your entity manager factory and your entity manager every time you simply want to persist an entity is way too expensive. Also, you are not closing your entity manager factory.

The right way to do it is, create an entity manager factory and keep it available for the entire life of your application. Every time you start a conversation with your user (i.e. a transaction) then request from it a entity manager, use it to persist everything you want to persist and then close the entity manager.

When your application finishes, close the entity manager factory.

A second aspect that you might like to take into account is that certain exceptions already imply a rollback, for instance, any exeception thrown during commit execution. Therefore if you attempt a second rollback, then you will get a second exception which you are not handling.

I cannot guarantee anything of these changes would solve your problem, but they are certainly a good start.

That being said, it is not evident for me, from your code, where you are persisting more than one entity. I guess, more context is required.

I'd suggest somewhat like this:

public class DataAccessLayer {

    private EntityManagerFactory emf;

    public DataAccessLayer (){
    }

    public synchronized void start(){
       if(isStarted())
         throw new IllegalStateException("Already started");
       this.emf = Persistence.createEntityManagerFactory("AllmoviesPU");
    }

    public synchronized void stop(){
       if(!isStarted())
         throw new IllegalStateException("Not started");
       this.emf.close();
       this.emf = null;
    }

   public synchronized boolean isStarted(){
     return this.emf != null;
   }

    public void doPersistenceStuff(InputData o){
            if(!isStarted())
              throw new IllegalStateException("Not started");
        EntityManager em = emf.getEntityManager();
        EntityTransaction t = entityManager.getTransaction();
        try {
            t.begin();
            //do persistence stuff here
            t.commit();
        }
        catch (RollbackException e) {
            //transaction already rolledback
            throw new MyPersistenceException(e);
        }
        catch (Exception e) {
            t.rollback(); //manual rollback
            throw new MyPersistenceException(e);
        }
        em.close()
    }
}

And you can make sure the emf is closed when your application is finished (like when the user clicks the exit button, or when your server stops or shuts down) by invoking the stop() method in the data access layer instance.

0

精彩评论

暂无评论...
验证码 换一张
取 消