-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: @OneToOne (EntityA 1:0..1 EntityB)
PostPosted: Mon Nov 13, 2006 3:31 pm 
Newbie

Joined: Wed Oct 25, 2006 2:41 am
Posts: 7
Hello,

Having tried various experiments and 'googled' all over the place (as well as posting on JBoss EJB 3.0 forum), I'm unable to create two entities that create a one for one join which when reversed engineered into an ERD tool (eg. MySQL Workbench) shows up with the correct notation (i.e. a one to one join).

The scenario...

EntityA has a compound primary key (two fields) and various other non-key fields. EntityA can be associated with zero or one EntityB objects (but no more).

EntityB has one non-key field. For each EntityB there must be one and only one EntityA.

I don't want EntityB to have its own primary key (it's record is uniquely identified by EntityA's key fields)

How can I annotate both EntityA and EntityB to ensure the above cardinality and correct reverse engineering in a data modeling tool?

Thanks,

Matthew

Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.2

Mapping documents: Too many variations to mention

Code between sessionFactory.openSession() and session.close(): I just create an EntityManger then close it

Full stack trace of any exception that occurs: n/a

Name and version of the database you are using: MySQL 5.0

The generated SQL (show_sql=true): Numerous


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 7:01 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
one one side
@OneToOne @PrimaryKeyJoinColumn


and on the other side
@OneToOne(mappedBy="...", optional=false)

should work.

I don't know about the capabilities of your reverse engineering tool though

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Example...
PostPosted: Tue Nov 14, 2006 3:04 pm 
Newbie

Joined: Wed Oct 25, 2006 2:41 am
Posts: 7
Hello Emmanuel,

At the end of this message, I've included some test code that incorporates your above suggestion (as I've interpreted it, which in itself could be an issue).

The resulting DDL creates two tables that seem to be completely unrelated (they have the the same primary key, persumably because they share the same EntityKey object).

What I would like to be generated is EntityA with a primary key of 'id' (no other fields) and EntityB with a foreign key of 'id' and a single field called text.

I notice that when I put the @OneToOne annotations on the getter versus the member attribute, I get two blobs created in each table representing the other object.

Am I doing something wrong?

Thanks,

Matthew


Class: EntityA

Code:
@Entity
public class EntityA implements Serializable
{
   @EmbeddedId
   private EntityKey key;
   
   @OneToOne @PrimaryKeyJoinColumn
   private EntityB entityB;
   
   public EntityA()
   {
     
   }

   public EntityB getEntityB()
   {
      return entityB;
   }

   public void setEntityB(EntityB pEntityB)
   {
      entityB = pEntityB;
   }

   public EntityKey getKey()
   {
      return key;
   }

   public void setKey(EntityKey pKey)
   {
      key = pKey;
   }
}



Class: EntityB

Code:
@Entity
public class EntityB implements Serializable
{
   @EmbeddedId
   private EntityKey key;
   
   private String text;
   
   @OneToOne(mappedBy="entityB", optional = false)
   private EntityA entityA;
   
   public EntityB()
   {
     
   }

   public String getText()
   {
      return text;
   }

   public void setText(String pText)
   {
      text = pText;
   }

   public EntityA getEntityA()
   {
      return entityA;
   }

   public void setEntityA(EntityA pEntityA)
   {
      entityA = pEntityA;
   }

   public EntityKey getKey()
   {
      return key;
   }

   public void setKey(EntityKey pKey)
   {
      key = pKey;
   }
   
   
}


Class: EntityKey
Code:
@Embeddable
public class EntityKey implements Serializable
{
   private long id;

   public long getId()
   {
      return id;
   }

   public void setId(long pId)
   {
      id = pId;
   }
   
}


Top
 Profile  
 
 Post subject: ANN-300
PostPosted: Wed Nov 15, 2006 1:42 pm 
Newbie

Joined: Wed Oct 25, 2006 2:41 am
Posts: 7
Could my problem be related to http://opensource.atlassian.com/projects/hibernate/browse/ANN-300


Top
 Profile  
 
 Post subject: Stop gap solution...
PostPosted: Wed Nov 15, 2006 7:48 pm 
Newbie

Joined: Wed Oct 25, 2006 2:41 am
Posts: 7
Whilst not perfect (as both EntityA and EntityB need to be persisted manually instead of just being able to populate EntityA with EntityB and persist EntityA), the following code for EntityA and EntityB built the relationships the way I wanted (as viewed in MySQL workbench). A one to many relationship is displayed by the workbench, but due to the sharing of the primary key of EntityA with that of EntityB, the relationship is effectively one to one.

As an added bonus, the named query works.

What would be really nice is when I call setEntityB (on EntityA) or setEntityA (on EntityB), I only have to persist one of the entity objects and that the 'if' code in the setEntityXX(...) methods was not necessary.


Class: EntityA
Code:
@Entity
@NamedQueries(
      {
         @NamedQuery(name = "EntityA.findByText", query = "select a from EntityA a join a.entityB b where b.text like :text")
      }
)
public class EntityA implements Serializable
{

   @EmbeddedId
   private EntityKey key;
   
   private int field;
   
   @OneToOne(optional = true)
   @PrimaryKeyJoinColumn
   private EntityB entityB;

   public EntityB getEntityB()
   {
      return entityB;
   }

   public void setEntityB(EntityB pEntityB)
   {
      entityB = pEntityB;
     
      if (entityB.getEntityA() != this)
      {
         entityB.setEntityA(this);
         entityB.setKey(getKey());
      }
   }

   public EntityA()
   {
     
   }

   public EntityKey getKey()
   {
      return key;
   }

   public void setKey(EntityKey pKey)
   {
      key = pKey;
   }

   public int getField()
   {
      return field;
   }

   public void setField(int pField)
   {
      field = pField;
   }
   
   
}


Class: EntityB
Code:
@Entity
public class EntityB implements Serializable
{
   @EmbeddedId
   private EntityKey key;
   
   private String text;

   @OneToOne(optional = false)
   @PrimaryKeyJoinColumn
   private EntityA entityA = null;

   public EntityB()
   {
     
   }

   public String getText()
   {
      return text;
   }

   public void setText(String pText)
   {
      text = pText;
   }

   public EntityKey getKey()
   {
      return key;
   }

   public void setKey(EntityKey pKey)
   {
      key = pKey;
   }
   

   public EntityA getEntityA()
   {
      return entityA;
   }

   public void setEntityA(EntityA pEntityA)
   {
      entityA = pEntityA;
     
      if (entityA.getEntityB() != this)
      {
         entityA.setEntityB(this);
         setKey(pEntityA.getKey());
      }
   }
   
   
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.