Micho Rizo
Micho Rizo

Reputation: 1092

Hibernate Mapping two tables with same PK value (NO FK col)

Im using hibernate and I have two tables with PK as varchar2

Table A
------- 
myId varchar2(40) **PK**
name varchar2(40)

Table B
-------- 
myId varchar2(40) **PK**
someItem varchar2(100)

Note there are no foreign key in either table and both myId are PK and should have the exact value after insertion.

I've tried OneToOne mapping but that seems to not like being mapped to a the Id

@Entity
@Table(name = "TABLE_A")
public class TableA {

@Id
@GeneratedValue( generator = "uuid")
@GenericGenerator(name = "uuid", strategy="uuid2")
@Column(name = "myId", length = 40, nullable = false)
private String id;

@Column(name = "name", length = 40, nullable = false)
private String name;

@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private TableB tableB;

}

2nd table

@Entity
@Table(name = "TABLE_B")
public class TableB {

@Id
@GeneratedValue( generator = "uuid")
@GenericGenerator(name = "uuid", strategy="uuid2")
@Column(name = "myId", length = 40, nullable = false)
private String id;

@Column(name = "someItem", length = 40, nullable = false)
private String anItem;

}

This produces an error stating that I need to define a id for class TableB before inserting. But I want the Id to be the same id for tableA. Is there a way to do this in hibernate?

Expected result:
Table_A
myId    name
=================
JK89S   Foobar

Table_B
myId   someItem
=================
JK89S  Razbaz

Upvotes: 0

Views: 76

Answers (1)

M46
M46

Reputation: 938

Well in my opinion, this doesn't make any sense. Every table MUST have it's own primary key to identify it's rows exactly. For example, if you create a table in a postgresql-database it will almost always automatically create a sequence unique to the created table.

If you want an id to be the same in two tables then it would be much better to let both tables have it's own primary key and add a second id which can be the same in both tables.

public class TableA {

@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.Identity)
private long id;

@Column(name="tablewide_id")
private long tableWideId;

@Column(name="item")
private String item;

...
}

This applies to Table B respectively.

If you don't want to create your "tableWideId" by hand you can create another table in your database and another class in your application.

public class TableWideId {

@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.Identity)
private long id;

... //Getter & Setter
}

Now you can do via a DAO

TableWideId id = new TableWideId();
long tableWideId = this.myDao.createTableWideId(id);

TableA tableA = new TableA(tableWideId);  // you need a proper Constructor
TableB tableB = new TableB(tableWideId);

// fill in the other properties

this.myDao.createTableA(tableA);
this.myDao.createTableB(tableB);

Now you have two tables with it's own primary keys and both share the same tableWideId.

Upvotes: 1

Related Questions