7 Replies Latest reply on Jul 16, 2007 10:10 AM by arougthopher

    RC6-PFD broke mappedBy and GenericGenerator workaround?

    dbudworth

      Hi Folks,

      First off, I'm using JBoss 4.0.4-GA (upgrading from 4.0.3SP1 + EJB3 RC5)
      It appears that the GenericGenerator / PrimaryKeyJoinColumn workaround no longer works.

      This was a work around I found on these message boards (and has been working for us in production for a while).

      Basic idea is we have an OWNER table with OWNER_ID as a column
      the other table is EMPLOYMENT with OWNER_ID as its primary key

      Ultimately we wanted to have Employment::getOwner() to be the PK field, but due to a limitation (either in the spec or the implementation, not sure) you couldn't have a bi-directional @OneToOne relationship where the PK of the child table was the parent table's ID.

      Is the workaround no longer needed? I'll try to test, just thought I'd check here since it will take a while to convert all my code.

      The problem occuring now is:

      org.hibernate.AnnotationException: Unknown mappedBy in: com.ezOptions.account.Owner.employment, referenced by property unknown: com.ezOptions.account.Employment.owner
      
      Emitted by: OneToOneSecondPass::doSecondPass(line 127)
      
      

      example:
      Owner{
       @OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="owner"
       public Employment getEmployment() { return employment; }
      }
      

      and
      Employment {
       @Id
       @GenericGenerator(name="fk", strategy="foreign", parameters={
       @Parameter(name="property", value="owner")
       })
       @GeneratedValue(strategy=GenerationType.AUTO, generator="fk")
       @Column(name="owner_id")
       public Long getId(){ return id; }
      
       @OneToOne
       @PrimaryKeyJoinColumn
       public AccountOwner getOwner(){ return owner; }
      }
      




        • 1. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
          dbudworth

          Small followup:

          In case it didn't make sense for what I was trying to do.

          I want child table's primary key to be a foreign key to the parent, and use entity accessors rather than having the child only have "Id".

          meaning:
          parent == parent.getChild().getParent()

          Rather than the 'normal'(per the hibernate docs) way of:
          parent.getId() == parent.getChild().getId()

          • 2. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
            epbernard

            This was not really meant to work previously. What should work is

            Owner{
             @OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
             @PrimaryKeyJoinColumn
             public Employment getEmployment() { return employment; }
            }
            

            and
            Employment {
             @Id
             @GenericGenerator(name="fk", strategy="foreign", parameters={
             @Parameter(name="property", value="owner")
             })
             @GeneratedValue(strategy=GenerationType.AUTO, generator="fk")
             @Column(name="owner_id")
             public Long getId(){ return id; }
            
             @OneToOne(mappedBy="employment")
             public AccountOwner getOwner(){ return owner; }
            }
            


            • 3. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
              dbudworth

              Thanks for the quick reply. It still doesn't seem to work though.

              Now the problem is on the other side of the relationship
              It seems as though the @OneToOne marked parent field is not considered when looking up the @OneToOne(mappedBy="") on the child

              I've looked over your response several times to make sure I'm not missing something. But for the life of me I can't see how my code is different.

              In case it matters, I do not actually need the Id field in the child. But as I read back in Feb on these boards, PK/FK mapping wasn't implemented yet and I don't think I've seen it go by in the release notes since then.
              The only reason I have getId() in the child class is so i can use the GenericGenerator thing to get at the parent object.

              I've tried skipping this one by removing the parent object reference and just using Id in the child to see if it was some odd bug with the fact that the child is AccountEntity but the parent calls it Entity, but that just moved the problem to the next class in the system.

              (copying from src/log now, so class names are different)

              log entry

              14:42:27,259 WARN [ServiceController] Problem starting service persistence.units:unitName=auth
              org.hibernate.AnnotationException: Unknown mappedBy in: com.ezOptions.account.dao.AccountEntity.account, referenced property unknown: com.ezOptions.account.dao.EZAccount.entity
               at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:127)
               at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1049)
              
              


              Relevant part of EZAccount (parent)
               @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
               @PrimaryKeyJoinColumn
               public AccountEntity getEntity() {
               return entity;
               }
              
               public void setEntity(AccountEntity entity) {
               this.entity = entity;
               }
              

              Relevant part of AccountEntity (child)
              @Id
               @GenericGenerator(name = "fk", strategy = "foreign", parameters = {
               @Parameter(name = "property", value = "account")
               })
               @GeneratedValue(strategy = GenerationType.AUTO, generator = "fk")
               @Column(name = "ezaccount_id")
               public Long getId() {
               return id;
               }
              
               public void setId(Long id) {
               this.id = id;
               }
              
               @OneToOne(mappedBy = "entity")
               public EZAccount getAccount() {
               return account;
               }
              
               public void setAccount(EZAccount account) {
               this.account = account;
               }
              


              • 4. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
                dbudworth

                Just dawned on me, is this supposed to actually work with vanilla EJB3 persistence?

                We've been using the workaround so long that I forgot we used hibernate specific annotations.

                Also, is there a test case / example out there that does this? Just thought I could stop pestering everyone if there was a source reference to this approach in action.

                • 6. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
                  ldebetaz

                  Is there a fix or workaround for the "unknown mappedBy" problem? No matter what I try I get this error. I have a Party (parent) and a Person (child) that I want to have the same primary key. The Party needs to control the creation of the primary key value and I want Person to use the same value. I've tried without the GenericGenerator - just trying to get the code to deploy without even worrying yet about setting the primary key correctly - and with the GenericGenerator but with no luck.

                  The code for Party:

                  @Entity
                  public class Party implements Serializable {
                  
                   @Id
                   @GeneratedValue(strategy=javax.persistence.GenerationType.AUTO)
                   public Long getId() {
                   return id;
                   }
                  
                   @OneToOne(optional=true, fetch=javax.persistence.FetchType.LAZY, mappedBy="party", cascade=javax.persistence.CascadeType.ALL)
                   public Person getPerson() {
                   return person;
                   }
                  
                  


                  Code for Person
                  @Entity
                  public class Person implements Serializable {
                   @Id
                   @GeneratedValue(generator="foreign")
                   @GenericGenerator(name="foreign",strategy="foreign",
                   parameters={@Parameter(name="property",value="party")})
                   public Long getId() {
                   return id;
                  
                   @OneToOne(fetch=javax.persistence.FetchType.EAGER,cascade=javax.persistence.CascadeType.ALL)
                   @PrimaryKeyJoinColumn
                   public Party getParty() {
                   return party;
                   }
                  


                  And I get this error
                  DEBUG 14-09 10:57:50,671 (PropertyBinder.java:make:122) -Building property person
                  DEBUG 14-09 10:57:50,671 (PropertyBinder.java:make:157) -Cascading person with all
                  ERROR 14-09 10:57:50,687 (AbstractController.java:incrementState:350) -Error installing to Start: name=persistence.units:jar=classes.jar,unitName=try_talyor_prj state=Create
                  org.hibernate.AnnotationException: Unknown mappedBy in: com.ndo.healthcare.entities.Party.person, referenced property unknown: com.ndo.healthcare.entities.Person.party
                   at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:127)
                   at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1049)
                   at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:302)
                   at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1034)
                   at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1015)
                   at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:154)
                   at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:751)
                   at org.hibernate.ejb.Ejb3Configuration.createContainerEntityManagerFactory(Ejb3Configuration.java:350)
                   at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:119)
                   at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:264)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                   at java.lang.reflect.Method.invoke(Unknown Source)
                   at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:55)
                   at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:107)
                   at org.jboss.joinpoint.plugins.BasicMethodJoinPoint.dispatch(BasicMethodJoinPoint.java:66)
                   at org.jboss.kernel.plugins.dependency.KernelControllerContextActions.dispatchJoinPoint(KernelControllerContextActions.java:100)
                   at org.jboss.kernel.plugins.dependency.KernelControllerContextActions$LifecycleAction.installAction(KernelControllerContextActions.java:582)
                   at org.jboss.kernel.plugins.dependency.KernelControllerContextActions$KernelControllerContextAction.install(KernelControllerContextActions.java:175)
                   at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
                   at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:226)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:593)
                   at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:346)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:438)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:379)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:225)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:151)
                   at org.jboss.kernel.plugins.dependency.AbstractKernelController.install(AbstractKernelController.java:79)
                   at org.jboss.kernel.plugins.dependency.AbstractKernelController.install(AbstractKernelController.java:73)
                   at org.jboss.ejb3.MCKernelAbstraction.install(MCKernelAbstraction.java:91)
                   at org.jboss.ejb3.Ejb3Deployment.startPersistenceUnits(Ejb3Deployment.java:626)
                   at org.jboss.ejb3.Ejb3Deployment.start(Ejb3Deployment.java:475)
                   at org.jboss.ejb3.embedded.EJB3StandaloneDeployer.start(EJB3StandaloneDeployer.java:460)
                   at org.jboss.ejb3.embedded.EJB3StandaloneBootstrap.scanClasspath(EJB3StandaloneBootstrap.java:291)
                   at net.taylor.jboss.EJB3Container.startupEmbeddedJboss(EJB3Container.java:63)
                   at net.taylor.jboss.EJB3Container.setUp(EJB3Container.java:31)
                   at junit.extensions.TestSetup$1.protect(TestSetup.java:18)
                   at junit.framework.TestResult.runProtected(TestResult.java:124)
                   at junit.extensions.TestSetup.run(TestSetup.java:23)
                   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
                   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
                   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
                   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
                   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
                  
                  


                  Am I modeling this wrong? Any help would be greatly appreciated.

                  • 7. Re: RC6-PFD broke mappedBy and GenericGenerator workaround?
                    arougthopher

                    We were having the same problem. We are using the 4.2.0 release, which includes Hibernate 3.2.1-GA. We started looking at some of the unit tests for hibernate annotations and found that something has changed between 3.2.1 and 3.3 releases. Looking at the org.hibernate.test.annotations.onotoone package, there are two classes, Party and PartyAffiliate.

                    The datamodel for this is such that Party has a unique partyId column, and PartyAffiliate uses the partyId for its PK as well, creating a PrimaryKeyJoinColumn reference.

                    In 3.2.1:
                    Party.java

                    @Entity
                    public class Party {
                     @Id
                     String partyId;
                    
                     @OneToOne(mappedBy = "party")
                     PartyAffiliate partyAffiliate;
                    }
                    

                    PartyAffliate.java
                    @Entity
                    public class PartyAffiliate {
                     @Id
                     String partyId;
                    
                     @OneToOne
                     @PrimaryKeyJoinColumn
                     Party party;
                    
                     String affiliateName;
                    }
                    


                    However, in 3.3, we have:
                    Party.java
                    @Entity
                    public class Party {
                     @Id
                     String partyId;
                    
                     @OneToOne
                     @PrimaryKeyJoinColumn
                     PartyAffiliate partyAffiliate;
                    }
                    

                    PartyAfiliate.java
                    @Entity
                    public class PartyAffiliate {
                     @Id
                     String partyId;
                    
                     @OneToOne(mappedBy="partyAffiliate")
                     Party party;
                    
                     String affiliateName;
                    }
                    



                    As you can see, the roles have changed. My question is, which is really right according to the spec?


                    We have a book here that implements their examples the way 3.2.1 did.
                    We have also used IntelliJ-IDEA to auto-gen the entity beans from the model, and it did so the way 3.2.1 did.
                    Jboss 4.2.0 contains hibernate annoations 3.2.1-ga, but it fails when running in the style of 3.2.1. If we flip like the 3.3 example does, it works


                    Either way we have it working, but, based on the fact that both a book and a third party have implemented it the way that the 3.2.1 examples have it, it seems that there might be a but in hibernate related to this.