Hibernate:session.get(...)vs session.getNamedQuery(...)

时间:2015-06-09 08:38:41

标签: java hibernate dao hibernate-session

在交易过程中,我创建/保存一个对象,然后在事务结束旁边再次读取对象(在设置历史事件之前)

@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;
    }
}

DAO

@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(...)时。对于acteur,我总是得到null值。 之前调用的方法creerActeur(Integer pkDeclaration, Acteur acteur)在会话中保存actor但不将其持久保存到数据库中。 事实上,演员只在交易结束时才会被持久化。

当我们从会话session.get(Acteur.class, pkActeur)获取对象时,问题就解决了。 我得到的对象就像我想要的那样。

我的问题是: 为什么我在执行查询“Declaration_Acteur_Complet”时看不到对象actor(在DB中)?是否涉及多个交易? session.get(...)session.getNamedQuery(...)之间有什么区别?

谢谢你的帮助。

3 个答案:

答案 0 :(得分:1)

  

session.get(...)和session.getNamedQuery(...)之间有什么区别?

  • session.get(MyClass.class,id)将从数据库加载具有相应id的实体MyClass
  • session.getNamedQuery(' myNamedQuery')。uniqueResult()将执行命名查询
  

为什么在执行查询" Declaration_Acteur_Complet"

时,我无法看到objet actor(在DB中)

这取决于命名查询背后的内容' Declaration_Acteur_Avec_Assurance'。它位于代码中的其他位置。也许是Acteur类或xml文件。

  

是否涉及多个交易?

没有

答案 1 :(得分:0)

您正在使用sessionFactory.getCurrentSession(),它为您提供了一个Spring托管会话bean。通常你会得到一个例外(没有活动的交易),但是你没有因为你已经将@Transactional放在你的UIService上,所以它将整个ajouterPersonneImpliquee()方法包装成一个交易。

刷新时间取决于你拥有的spring-hibernate配置。因此,如果我理解正确,您可以在session.flush()之后调用session.save(),或者在UIService中使用其他方法调用creerActeGestionActeur(),以便弹簧正确包装。

答案 2 :(得分:0)

感谢您的回答。

查询' Declaration_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());

事实上,我有对象&#39; personneImpliquee&#39;而且我不需要为我的流程调用此方法。 有关信息,我使用最新技术重构旧应用程序。