Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Many-To-One Relationship without Foreign Key but with reverse foreign key

I have the following DB:

CREATE TABLE car_owner (
  car_owner_id int(11) NOT NULL,
  car_id_fk int(11) DEFAULT NULL,
  PRIMARY KEY (car_owner_id),
  KEY car_owner_car_fk_idx (car_id_fk),
  CONSTRAINT car_owner_car_fk FOREIGN KEY (car_id_fk) REFERENCES car (car_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


CREATE TABLE car (
   car_id int(11) NOT NULL AUTO_INCREMENT,
   car_type varchar(45) DEFAULT NULL,
   car_plates varchar(25) DEFAULT NULL,
  PRIMARY KEY (car_id),
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

And In the java model:

For CarOwner I have:

@Entity
@Table(name="car_owner")
@NamedQuery(name="CarOwner.findAll", query="SELECT co FROM CarOwner co")
public class CarOwner implements Serializable {

    @Id
    @GeneratedValue
    @Column(name="car_owner_id")
    private Integer carOwnerId;
.....

    //bi-directional many-to-one association to Car
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "car_id_fk", referencedColumnName = "car_id")
    private List<Car> cars;

And for Car:

@Entity
@Table(name="car")
@NamedQuery(name="Car.findAll", query="SELECT c FROM Car c")
public class Car implements Serializable {

    @Id
    @GeneratedValue
    @Column(name="car_id")
    private Integer carId;
......

    //bi-directional many-to-one association to car_owner
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name = "car_owner_id")
    private CarOwner carOwner;

The problem here is that Hibernate can't relate the tables and goes creating new car_id and car_owner_id columns in car table automatically.

Can anybody help in finding the right combination in the model to relate the tables appropriately.

like image 610
GingerHead Avatar asked Nov 06 '25 06:11

GingerHead


1 Answers

@JoinColumn should be in owner of relationship (in a one to many it's the many side that's regarded the owner).

So I will modify this in car

 @ManyToOne(fetch=FetchType.EAGER)
 @JoinColumn(name = "car_owner_id",insertable=false, updatable=false)
 private CarOwner carOwner;

And this in CarOwner

@OneToMany(fetch = FetchType.EAGER,mappedBy = "carOwner")
 private List<Car> cars;

As a side note I would also not be using EAGER but that has got nothing to do with question.


Both tables knowing about each other is called Bi-directional relationship.This happens when each table has a key to other table. This is what your java code is expecting.Your tables in database however have a uni-directional relationship. Meaning one table knows about the other but not both. Your car_owner knows about car because of foriegn key CONSTRAINT car_owner_car_fk FOREIGN KEY but your car does not have any idea about car_owner both are perfectly valid.

Now the problem is that in your Java code you are treating it as a bi-directional relationship.

//bi-directional many-to-one association to car_owner
 @ManyToOne(fetch=FetchType.EAGER)
 @JoinColumn(name = "car_owner_id")
 private CarOwner carOwner;

but car does not have car_owner_id why are you treating it a Bi-directional relationship.

Now either update database to make them bi or change java code.

like image 176
Shahzeb Avatar answered Nov 08 '25 10:11

Shahzeb