Pergunta

I have a OneToMany connection between tables Result and ResultAux. I can retrieve a set of ResultAux objects from Result. After that I'm adding some ResultAux objects to set and using merge on each set entry to flush changes into database. Like this:

Set<ResultAux> resultAuxes = result.getResultAuxes();
if (resultAuxes != null) {
    for (ResultAux resultAux : resultAuxes) {
        resultAux = getDaoFactory().getResultAuxDAO().merge(resultAux);
    }
}

For some additional actions i need to know is set entry a new record and will be inserted into table or it's an old one and (modified or not) will be updated. I noticed that all entries of ResultAux set already have an ID, so i can't check it for null as i did for other tables. Is there any way to determine such thing (prefferably not involving extra libs)?

EDIT:

<hibernate-mapping>
    <class name="ResultAux" table="RESULT_AUX">
        <id name="id" column="ID">
            <generator class="native" />
        </id>

        <property name="additinalInfoType" column="AITYPE" type="dao.hibernate.utl.AdditinalInfoEnumType" />
        <property name="sorter" column="SORTER" />
        <property name="value1" column="VAL1" />
        <property name="value2" column="VAL2" />

        <many-to-one name="result" column="RESULT_ID" class="Result" />
    </class>
</hibernate-mapping>

<hibernate-mapping>
    <class name="Result" table="RESULT">
        <id name="id" column="ID">
            <generator class="native" />
        </id>

        <property name="questionNumber" column="Q_NUM" />
        <property name="answerNumber" column="A_NUM" />
        <property name="questionGroup" column="Q_GRP" />
        <property name="answerValue" column="A_VAL" />
        <set name="resultAuxes" inverse="true" cascade="all-delete-orphan"
            lazy="false">
            <key column="RESULT_ID" />
            <one-to-many class="ResultAux" />
        </set>
    </class>
</hibernate-mapping>
Foi útil?

Solução

Using native as the the primary key generation strategy causes Hibernate to select identity, sequence or hilo as the PK generation strategy depending upon the capabilities of the underlying DB.

I think for your DB , hibernate selects "sequence" strategy such that you may experience this problem (Records that are not inserted to the DB can have the assigned ID) by the following codes:

Set<ResultAux> resultAuxes = result.getResultAuxes();
ResultAux  newResultAux = new ResultAux();

/**
 * As session.save()  requires to return the ID for the saved instance , if  "sequence" strategy is 
 * used , Hibernate will hit the DB  to select the next ID (eg. select some_seq.NEXTVAL) to be used 
 * for the saved instance. So newResultAux  will have an ID after save()  but actually it is not saved to 
 * the DB yet as  saving to the DB  occurs during session.flush()
 */
session.save(newResultAux);
resultAuxes.add(newResultAux);

One of the solutions is to add a @Version property to the ResultAux . Then you could check the value of this @Version property to determine whether it is a new record or not as the @Version property for a new record must be NULL

Outras dicas

I'm not sure my answer will resolve your problem, but to come back on @EugenioCuevas comment, I would have done something like this to persist your child entities:

Set<ResultAux> resultAuxes = result.getResultAuxes();
if (resultAuxes != null) {
    for (ResultAux resultAux : resultAuxes) {
        resultAux.setResult(result);
    }
}
getDaoFactory().getResultDAO().merge(result);

Hibernate should then manage the relations on its own.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top