2 Replies Latest reply on Jun 16, 2009 2:44 AM by ngonjp

    How to stop Hibernate trying to find missing assosiated enti

    ngonjp

      Hello,

      I have a Person which has many to one assosication to Nationality.
      I trid to get a revison entity of person which once had a nationality(at rev.100)
      and had no (null) nationality(at rev.110) by forRevisionsOfEntity.
      I can successfully get the revision entity(rev.110). But when I call person.getNationality()
      to check if the person has nationality or not, I've got exceptions.

      It seems that Hibernate try to seek natinality Instance with id null.
      I expect .getNationality() returns null.

      Are there any workaround?

      [Person.java]

      @Entity
      @Audited
      public class Person implements Serializable {
       @Id
       @GeneratedValue
       private long personId;
      
       @Column
       private String name;
      
       @ManyToOne(targetEntity = Nationality.class)
       @JoinColumn(name = "nationalityId",
       referencedColumnName = "nationalityId")
       private Nationality nationality;
      
       // getters / setters ...
      }
      


      [Nationality.java]
      @Entity
      @Audited
      public class Nationality implements Serializable {
       @Id
       @GeneratedValue
       private Long nationalityId;
      
       @Column
       private String name;
      
       // getters / setters ...
      }


      1) I created a new Person with Nationality and persisted. [rev.100]
      Person person = new Person();
       person.setName("Naoki");
       person.setNationality(entityManager.find(Nationality.class, (long) 1));
       entityManager.persist(person);
       entityManager.flush();
      

      2) I load the Person instance and set the nationality to null. [rev.110]
      naoki.setNationality(null);
       entityManager.persist(naoki);
       entityManager.flush();
      

      3) I got an Exception when I queried revisions by forRevisionsOfEntity.
      revsOfEntityQry = reader.createQuery().forRevisionsOfEntity(Person.class, false, false);
       List<Object []> revs = (ArrayList<Object []>) revsOfEntityQry
       .add(AuditEntity.id().eq(naoki.getPersonId())).getResultList();
      
       for (Object obj[] : revs) {
       DefaultRevisionEntity r = (DefaultRevisionEntity)obj[1];
       Person naokirev = (Person)obj[0];
      
       Nationality national = naokirev.getNationality();
       if (national != null) {
       if (national.getNationalityId() != null) { // <=== !!!! Exception raised !!!!
       System.out.println("Yes, I have a nationality : " + national.getName());
       } else {
       System.out.println("Yes, I have a nationality : " + national.getName());
       }
       } else {
       System.out.println("No, I don't");
       }
      

      Stacs are here.

      14:22:37,592 INFO [STDOUT] Hibernate:
      select
      national0_.nationality_id as national1_138_,
      national0_.rev as rev138_,
      national0_.revtype as revtype138_,
      national0_.name as name138_
      from
      nationality_aud national0_
      where
      national0_.revtype<>?
      and national0_.rev=(
      select
      max(national1_.rev)
      from
      nationality_aud national1_
      where
      national1_.rev<=?
      and national0_.nationality_id=national1_.nationality_id
      )
      and national0_.nationality_id=?
      14:22:37,623 ERROR [application] javax.ejb.EJBTransactionRolledbackException: Unable to find mytest.Nationality with id null
      javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: Unable to find mytest.Nationality with id null
      at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
      at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
      at javax.faces.component.UICommand.broadcast(UICommand.java:387)
      at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
      at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
      at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
      at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
      :