2016-09-08 2 views
0

Я создал класс репозитория (класс, который обрабатывает все методы jpa) для каждого типа сущности с помощью собственной entitymanagerfactory. Теперь я столкнулся следующее сообщение об ошибке на мой отношения многие ко многим:Имеет ли использование отдельного объекта entitymanagerfactory для каждого объекта проблемы?

ValidationException [junit][EclipseLink-7251] Exception Description: The attribute [ID] of class [Person] is mapped to a primary key column in the database. Updates are not allowed.

Эта ошибка часто не происходит больше при отладке и не кажется, появляются последовательно, что приводит меня в это поверить может быть проблемой синхронизации между менеджерами. (Pk обрабатывается jpa - @Id @GeneratedValue - и никогда меня не меняет, я использую каскадное слияние)

Я исхожу в своем предположении, что наличие нескольких объектов entitymanagerfactor является плохими идеями (и может быть связано к моим проблемам)?

+1

Почему бы вы идти о попытке изменить идентификатор объекта ?! Наличие нескольких EMF не поможет (и убьет вашу производительность). Исправление вашего кода (и вы не представляете код, который вызывает проблему). –

+0

Я не хочу менять идентификатор объекта, я использую @generated, чтобы jpa инициализировал идентификатор и намерен сохранить идентификатор, как есть. Мой мыслительный процесс состоял в том, что, поскольку менеджеры не синхронизировались, возможно, это заставляет их хотеть генерировать идентификатор второй раз, вызывая тем самым ошибку. – Wouter

+0

Итак, отправьте КОД, который выдает исключение, и тогда люди могут видеть, ЧТО его вызывает. Что (жизненный цикл) - это объекты, когда вы выполняете какую-либо операцию? –

ответ

0

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

(я думаю, что это произошло, когда 2 разных экземпляров одного и того же объекта управлялись в 2-х разных контекстах и ​​один из экземпляров изменили это состояние, хотя я не уверен)

Испытано как это:

примечания:

  • orderweek (= сторона, не принадлежащая стороне) имеет одно к одному двунаправленную связь с неделей с помощью cascadeType.ALL.
  • orderRep и weekRep случаи выполнения операторов CRUD, связанные с Db, каждый со своим собственным менеджером сущностей, созданных с их собственной EMF
  • В 2 ЭДС созданы в отдельно фабричных классов, но связаны с одной и той же БД и должен использовать один и тот же блок сохранения «BreadPU».
  • С тех пор я понял, что несколько э.д.с. к тому же источнику данных является плохой идеей

(соответствующая часть методы испытания JUnit)

OrderBill cheapOrder = new OrderBill(5, LocalDate.now()); 
weekRep.addWeek(cheapOrder.getOrderWeek()); 
//because of the cascade, both the cheapOrder and the week or now persisted in the DB and managed by weekRep 

OrderBill dbOrder = orderRep.updateOrder(cheapOrder); 
boolean t2 = weekRep.isManaged(cheapOrder); //true 
boolean t3 = orderRep.isManaged(cheapOrder); //false 
//It's because this returns false I assume both persistence contexts are different 
boolean t4 = orderRep.isManaged(dbOrder); //true 
//If i now use "cheapOrder" to change the order i get the error 
//If i now use "dbOrder" to change the order, db gets updated as expected 
1

EntityManagerFactory представляет собой один постоянный блок или, другими словами, один источник данных. Если у вас нет нескольких источников данных, вам не следует создавать многопользовательскую EMF. Вы можете создать несколько EntityManager (что вы можете представить как «соединения» с базой данных).

Вы создаете EMF, как это -

EntityManagerFactory emf = Persistence.createEntityManagerFactory(
    "objectdb://localhost/myDbFile.odb;user=admin;password=admin") 

или

EntityManagerFactory emf = 
    Persistence.createEntityManagerFactory("myDbFile.odb"); 

и создавать EntityManager как это -

EntityManager em = emf.createEntityManager(); 

От Javadoc - http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManagerFactory.html

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

Добавление более, что вам могут понадобиться транзакции, а также которые вы можете создать, как это -

try { 
    em.getTransaction().begin(); 
    // Operations that modify the database should come here. 
    em.getTransaction().commit(); 
    } 
    finally { 
    if (em.getTransaction().isActive()) 
     em.getTransaction().rollback(); 
    } 
+0

Я не могу принять ваш ответ, так как он действительно не затрагивает мой первоначальный вопрос, но вы даете хорошее объяснение тому, что EMF (и несколько EMF - это плохая практика здесь) среди других, так что вы определенно заработали мое преимущество – Wouter

Смежные вопросы