2015-06-09 2 views
1

В процессе транзакции я создаю/сохраняю объект, а рядом с завершением транзакции я снова читаю объект (перед установкой события истории)Hibernate: session.get (...) vs session.getNamedQuery (...)

@org.springframework.stereotype.Service 
@Transactional(value="transactionManager") 
public class UTServiceImpl implements UTService { 
    private static final Logger logger = Logger.getLogger(UTServiceImpl.class); 
    ... 

    @Autowired 
    private DeclarationDao declarationDao; 
... 

public Integer ajouterPersonneImpliquee(ContexteService contexte, Integer pkQualification, Integer pkUT, Acteur personneImpliquee) throws ExceptionValidation { 
... 

      pk = declarationDao.creerActeur(pkDeclaration, personneImpliquee); 

....   

     // History 
     personneImpliquee = declarationDao.rechercherActeurAvecAssurance(personneImpliquee.getPk()); 
     creerActeGestionActeur(creationActeur, personneImpliquee, contexte.getIdentifiantUtilisateur(), declaration, ut); 

     return pk; 
    } 
} 

дао

@Repository 
public class DeclarationDaoImpl implements DeclarationDao { 
    private Logger logger; 

    @Autowired @Qualifier("sessionFactorySinistre") 
    private SessionFactory sf; 

    public DeclarationDaoImpl() { 

    } 
.... 

public Integer creerActeur(Integer pkDeclaration, Acteur acteur) { 
     final Session session = sf.getCurrentSession(); 

     // On retrouve la déclaration 
     Declaration declaration = (Declaration) session.get(Declaration.class, pkDeclaration); 
     if (declaration == null) { 
      throw new ExceptionPkEntiteInconnu(Declaration.class, pkDeclaration); 
     } 

     // On ne persiste pas la personne quand c'est un sociétaire, appel NOA systématique 
     if (Acteur.TYPE_SOCIETAIRE.equals(acteur.getTypePersonne())) { 
      acteur.setPersonne(null); 
     } 

     declaration.getActeurs().add(acteur); 
     session.save(acteur); 
     return acteur.getPk(); 
    } 
... 
    public Acteur rechercherActeurAvecAssurance(Integer pkActeur) { 
     final Session session = sf.getCurrentSession(); 

     Query query = session.getNamedQuery("Declaration_Acteur_Avec_Assurance"); 
     query.setInteger(0, pkActeur.intValue()); 
     Acteur acteur = (Acteur) query.uniqueResult(); 

     // On met la personne en cas de sociétaire 
     if (Acteur.TYPE_SOCIETAIRE.equals(acteur.getTypePersonne())) { 
      // Il faut ABSOLUMENT détacher l'objet de la session pour ne pas persister la personne rajoutee au flush !!! 
      session.evict(acteur); 
     } 
     return acteur; 
    } 
... 
} 

Когда я использую session.getNamedQuery(...). Я всегда имел значение null для объекта acteur. Вызывается метод creerActeur(Integer pkDeclaration, Acteur acteur) перед сохранением актера в сеансе, но не сохраняется в базе данных. Фактически, актер сохраняется только в конце транзакции.

Проблема решена, когда мы получили объект из сеанса session.get(Acteur.class, pkActeur). Я получил объект acteur, как я хочу.

Мои вопросы: Почему я не вижу объекта-актера (в БД) при выполнении запроса «Декларация_Актер_комплект»? Существует ли более одной транзакции? В чем разница между session.get(...) и session.getNamedQuery(...)?

Спасибо вам за помощь.

+0

session.getNamedQuery (...) выполняет заданный запрос, идентифицированный по имени в вашем случае «Declaration_Acteur_Avec_Assurance», session.get (Acteur.class, pkActeur) выполняет простой SELECT * FROM ActeurTable WHERE ActeurPK = pkActeur. – Zelldon

ответ

0

Вы используете sessionFactory.getCurrentSession(), который дает вам управляемый сеансом сеанса. Обычно вы получаете исключение (без активной транзакции), но вы не вызываете, что вы разместили @Transactional на своем UIService, чтобы он обернул весь метод ajouterPersonneImpliquee() в одну транзакцию.

Время сброса зависит от конфигурации пружины-гибернации. Поэтому, если я правильно понял, вы можете позвонить по телефону session.flush() после session.save() или позвонить по номеру creerActeGestionActeur() в другом методе в UIService, чтобы он был правильно упакован весной.

1

В чем разница между session.get (...) и session.getNamedQuery (...)?

  • session.get (MyClass.class, идентификатор) будет загружаться из базы данных объекта MyClass с соответствующим идентификатором
  • session.getNamedQuery ('myNamedQuery'). UniqueResult() будет выполнять запрос с именем

Почему я не могу увидеть Objet актера (в БД), когда я выполняю запрос «Declaration_Acteur_Complet»?

Это зависит от того, что находится за именованным запросом «Declaration_Acteur_Avec_Assurance». Он находится где-то еще в вашем коде. Возможно, класс Acteur или в XML-файле.

Имеются ли более чем одна сделка?

Нет

0

Спасибо за ответы.

Запрос «Декларация_Acteur_Avec_Assurance» в моем hbm.XML:

<query name="Declaration_Acteur_Avec_Assurance"><![CDATA[ 
     select act from com.prima.solutions.primaclaims.core.modele.sinistre.declaration.Acteur act 
     left join fetch act.personne 
     left join fetch act.assureur assu left join fetch assu.personne 
     left join fetch act.intermediaire inter left join fetch inter.personne 
     left join fetch act.correspondantAssureur corr left join fetch corr.personne 
     where act.pk = ? 
    ]]></query> 

Я решил эту проблему, не делая

personneImpliquee = declarationDao.rechercherActeurAvecAssurance(personneImpliquee.getPk()); 

На самом деле, у меня есть объект «personneImpliquee» и мне не нужно вызывать этот метод для моего процесса. Для информации, я реорганизую старое приложение с использованием новейших технологий.

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