Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA (Hibernate) issue with OneToOne mappedBy annotation

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
...
like image 237
user6123723 Avatar asked Aug 18 '13 20:08

user6123723


People also ask

What is MappedBy in Hibernate?

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.

How do I map a OneToOne JPA?

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.

What is MappedBy in JPA?

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.

What is difference between JPA unidirectional OneToOne and ManyToOne?

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.


1 Answers

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.

like image 181
Kevin Bowersox Avatar answered Sep 28 '22 21:09

Kevin Bowersox