I have two tables for while I setup a oneToOne relationship. Bill and BillSimpleEntry. (Each Bill has one BillSimpleEntry
Here is their structure
CREATE TABLE `bill` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
..
..
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `fk_bill_groups1_idx` (`groupId`),
KEY `fk_bill_user1_idx` (`billPayerId`),
CONSTRAINT `fk_b...` FOREIGN KEY (`groupId`) REFERENCES `groups` (`id`) ON D ELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_b...` FOREIGN KEY (`billPayerId`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `billsimpleentry`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `billsimpleentry` (
`..` varchar(200) DEFAULT NULL,
`..` text,
`billId` bigint(20) DEFAULT NULL,
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `fk_bill_idx` (`billId`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
JPA config (snippet from the bill Entity for the oneToOne relationship attribute).
@OneToOne(cascade=CascadeType.ALL,mappedBy="billId",fetch = FetchType.EAGER)
private BillSimpleEntry billSimpleEntry;
I'm trying to do a Join between Bill and BillSimpleEntry by billSimpleEntry.billId and bill.Id. But I seem to get an error.
Here is the error I get-
Caused by: org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne:
com.uh.br.domain.BillSimpleEntry.billId in mappedBy of
com.uh.br.domain.Bill.billSimpleEntryry
Here are the entities
Bill.java
@Entity
@Table(name = "bill")
public class Bill implements GenericObject {
/**
*
*/
private static final long serialVersionUID = -5660869020353250221L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
..
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name="billId")
private BillSimpleEntry billSimpleEntry;
...
getters & setters
...
}
BillSimpleEntry.java
@Entity
@Table(name="billsimpleentry")
public class BillSimpleEntry implements GenericObject{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long billId;
@Column(columnDefinition="TEXT")
private String itemDescription;//napkin
...
...
...
getters & setters
...
MappedBy signals hibernate that the key for the relationship is on the other side. This means that although you link 2 tables together, only 1 of those tables has a foreign key constraint to the other one. MappedBy allows you to still link from the table not containing the constraint to the other table.
The best way to map a @OneToOne relationship is to use @MapsId . This way, you don't even need a bidirectional association since you can always fetch the PostDetails entity by using the Post entity identifier. This way, the id property serves as both Primary Key and Foreign Key.
The purpose of the MappedBy parameter is to instruct JPA: Do NOT create another join table as the relationship is already being mapped by the opposite entity of this relationship.
According to book Pro JPA 2 the main difference between unidirectional @ManyToOne and @OneToOne is that in @OneToOne: Only one instance of the source entity can refer to the same target entity instance. In other words, the target entity instance is not shared among the source entity instances.
The mappedBy
attribute is only necessary for a bidirectional
relationship, this element can be omitted on the annotation. It is used on the source entity to point back to a field on the target entity that defines the relationship (contains @JoinColumn).
The @JoinColumn
annotation should be placed upon the billSimpleEntry
field to define the column that should be used to join the two tables. In the case of a OneToOne
the following applies:
If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or embeddable.
Here is a code example:
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name="id")
private BillSimpleEntry billSimpleEntry;
Also, if the Bill
will contain the SimpleBillEntry
field the BILL
table should contain a foreign key to the billsimpleentry
table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With