Как предотвратить EclipseLink (JPA 2.0) от очистки моей базы данных / таблицы? - PullRequest
2 голосов
/ 18 мая 2011

Я использую EclipseLink (JPA 2.0) на Netbeans 7.0 с базой данных MySQL - которую я настроил в соответствии с этой экранной передачей . Но иногда, когда я сохраняю объект / сущность, моя таблица очищается до того, как этот объект сохраняется, и я получаю таблицу только с этим объектом (как будто он был очищен). Я просто добавляю новые записи в (заполняю) базу данных.

Как я могу предотвратить это?

Вот мой код:

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);

Моя функция persist ():

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:

@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 year, 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>

Ответы [ 2 ]

3 голосов
/ 19 мая 2011

Попробуйте включить запись в FINEST или FINE, чтобы увидеть, что происходит.("eclipselink.logging.level" = "finest").

EclipseLink имеет возможность воссоздать таблицы при запуске ("eclipselink.ddl-generation" = "drop-and-create-tables"),убедитесь, что вы не используете это.NetBeans или Glassfish могут устанавливать это по умолчанию, я думаю, что они могут делать это в режиме разработки.

2 голосов
/ 18 мая 2011

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

Во-первых, создание вашей фабрики менеджеров сущностей и менеджера сущностей каждый раз, когда вы просто хотите сохранить сущность, слишком дорого. Кроме того, вы не закрываете свою фабрику менеджеров сущностей.

Правильный способ сделать это - создать фабрику управления сущностями и поддерживать ее доступной на протяжении всего срока службы вашего приложения. Каждый раз, когда вы начинаете разговор с вашим пользователем (то есть транзакцию), затем запрашиваете у него менеджера сущностей, используйте его для сохранения всего, что вы хотите сохранить, и затем закрываете менеджера сущностей.

Когда ваше приложение завершит работу, закройте фабрику менеджера сущностей.

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

Я не могу гарантировать, что что-то из этих изменений решит вашу проблему, но это, безусловно, хорошее начало.

Это, как говорится, для меня не очевидно из вашего кода, где вы сохраняете более чем одну сущность. Я думаю, требуется больше контекста.

Я бы предложил что-то вроде этого:

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()
    }
}

И вы можете убедиться, что ЭДС закрыта, когда ваше приложение будет завершено (например, когда пользователь нажимает кнопку выхода или когда ваш сервер останавливается или завершает работу), вызывая метод stop () в экземпляре уровня доступа к данным.

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