1 Reply Latest reply on Aug 10, 2006 4:21 PM by edvedafi

    Is Disciminator used in @OneToMany?

    edvedafi

      I have a Entity (A) that has a List of Bservices and one Baccount record. Bservice and Baccount both inherit from an abstract class B and are both stored in table B. The code below is how I thought it should work, but it does not. When I try to deploy it says there is a "broken column mapping a.id of B". If I change A to have a OneToMany relationship with Baccount it will deploy but then I get this exception in the client when I call a.getBs().

      javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.WrongClassException: Object with id: ... was not of the specified subclass: bAccount
      


      In an attempt to figure out what is going on I commented out all the relationship information for Baccount so that A had a set of Bservices, but knew nothing of Baccounts. In this case I got all the B records (both BService and Baccount) when I called a.getBs(). Does a Join ignore the DiscriminatorValues? Shouldn't the inheratence take care of not populating Bservice with records that have a different discriminator value? If so is there any way around this to only load Bservices into bs and Baccounts into bAccount, without writing a query for each and having to execute both queries to load the objects?

      @Entity
      @DiscriminatorValue(value="C")
      public class Bservice extends B implements java.io.Serializable {
      
       private A a;
      
       @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
       @JoinColumns( { @JoinColumn(name="LOC", insertable=false, updatable=false),
       @JoinColumn(name="CUST_NO", insertable=false, updatable=false),
       @JoinColumn(name="CYC_YEAR", insertable=false, updatable=false),
       @JoinColumn(name="CYC", insertable=false, updatable=false),
       @JoinColumn(name="CYC_END_DAY", insertable=false, updatable=false) } )
       public A getA() {
       return a;
       }
      
       public void setA(Aa) {
       this.a= a;
       }



      @Entity
      @DiscriminatorValue(value="A")
      public class Baccount extends B implements java.io.Serializable {
      
       private A a;
      
       @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
       @JoinColumns( { @JoinColumn(name="LOC", insertable=false, updatable=false),
       @JoinColumn(name="CUST_NO", insertable=false, updatable=false),
       @JoinColumn(name="CYC_YEAR", insertable=false, updatable=false),
       @JoinColumn(name="CYC", insertable=false, updatable=false),
       @JoinColumn(name="CYC_END_DAY", insertable=false, updatable=false) } )
       public Isumcust getIsumcust() {
       return isumcust;
       }
      
       public void setA(A a) {
       this.a= a;
       }
      }


      @Entity
      @Table(name="A")
      public class A implements java.io.Serializable {
      
       @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
       @JoinColumns( { @JoinColumn(name="LOC", insertable=false, updatable=false),
       @JoinColumn(name="CUST_NO", insertable=false, updatable=false),
       @JoinColumn(name="CYC_YEAR", insertable=false, updatable=false),
       @JoinColumn(name="CYC", insertable=false, updatable=false),
       @JoinColumn(name="CYC_END_DAY", insertable=false, updatable=false) } )
       public Set<Bservice> getBs()
       {
       return this.bs;
       }
      
       public void setIsummains( Set<Bservice> bs)
       {
       this.bs= bs;
       }
      
       @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
       @JoinColumns( { @JoinColumn(name="CUST_NO", referencedColumnName="CUST_NO", insertable=false, updatable=false),
       @JoinColumn(name="CYC_END_DAY", referencedColumnName="CYC_END_DAY", insertable=false, updatable=false),
       @JoinColumn(name="CYC", referencedColumnName="CYC", insertable=false, updatable=false),
       @JoinColumn(name="CYC_YEAR", referencedColumnName="CYC_YEAR", insertable=false, updatable=false),
       @JoinColumn(name="LOC", referencedColumnName="LOC", insertable=false, updatable=false) } )
       public Baccount getBaccount() {
       return this.bAccount;
       }
      
       public void setIsummainAccount(Baccount bAccount) {
       this.bAccount = bAccount;
       }
      
      }
      




        • 1. Re: Is Disciminator used in @OneToMany?
          edvedafi

          May be the problem isn't quite what I thought:

          Once I added referencedColumnName="" to all of the JoinColumns I was able to eliminate this problem. As well as an @WHERE(clause="type=A") annotation along with the JoinColumns it kindof works.

          However now I am noticing that on a OneToMany relationship it is including the discriminator, but on the OneToOne it is not. So if I make them both OneToMany relationships then everything is fine, but If I make Baccount a OneToOne it thorws an exceptions saying that more than one record has been returned. However if I make it a set the size of the set is always one just like it should be.

          I have also tried building another Entity that has only One OneToOne with another table that has a discriminator, and I see the same problem.

          When I look at the query that Hibernate generates the SQL of the OneToMany it has type=A in the where clause, but on the OneToOne it does not have this as part of the where clause even though I have the @Where annotation.

          Why can't I use @Where with a OneToOne relationship?