1

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

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

当我们从 session 中获取对象时,问题就解决了session.get(Acteur.class, pkActeur)。我得到了我想要的对象演员。

我的问题是:为什么我在执行查询“Declaration_Acteur_Complet”时看不到对象参与者(在 DB 中)?是否涉及不止一项交易?session.get(...)和 和有什么不一样session.getNamedQuery(...)

谢谢你的帮助。

4

3 回答 3

1

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

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

为什么我在执行查询“Declaration_Acteur_Complet”时看不到对象角色(在 DB 中)?

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

是否涉及不止一项交易?

于 2015-06-09T08:55:24.283 回答
0

您正在使用sessionFactory.getCurrentSession()它为您提供一个 Spring 托管会话 bean。通常你会得到一个异常(没有活动的事务),但你不会导致你已经放置@Transactional在你的 UIService 上,所以它将整个ajouterPersonneImpliquee()方法包装到一个事务中。

刷新时间取决于您拥有的 spring-hibernate 配置。因此,如果我理解正确,您可以调用session.flush()after session.save(),或者creerActeGestionActeur()在 UIService 中调用不同的方法,以便它被 spring 正确包装。

于 2015-06-09T08:54:40.053 回答
0

感谢您的回答。

在我的 hbm.xml 中查询“Declaration_Acteur_Avec_Assurance”:

<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”,我不需要为我的流程调用此方法。有关信息,我使用最新技术重构了一个旧应用程序。

于 2015-06-09T14:46:42.573 回答