简体   繁体   中英

Hibernate - one to one relation

I have two tables

User

CREATE TABLE "user"
(
    id INTEGER PRIMARY KEY NOT NULL,
    phone TEXT,
    position_id BIGINT,
    CONSTRAINT user_position_id_fk FOREIGN KEY (position_id) REFERENCES position (id)
);
CREATE UNIQUE INDEX user_id_uindex ON "user" (id);

Position

CREATE TABLE position
(
    id INTEGER PRIMARY KEY NOT NULL,
    latitude DOUBLE PRECISION,
    longitude DOUBLE PRECISION,
    bearing DOUBLE PRECISION,
    accuracy DOUBLE PRECISION,
    speed DOUBLE PRECISION,
    user_id BIGINT,
    CONSTRAINT position_user_id_fk FOREIGN KEY (user_id) REFERENCES "user" (id)
);
CREATE UNIQUE INDEX position_id_uindex ON position (id);

They are mapped by annotations like this:

@Entity
@Table(name = "user")
public class User {

    public static final String ID = "id";
    public static final String PHONE = "phone";

    public User() {
        position = new Position();
    }

    @Id
    @Column(name = ID, unique = true)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = PHONE)
    private String phone;

    @OneToOne(mappedBy = "user")
    @Cascade(CascadeType.ALL)
    @JoinColumn(name = "id", referencedColumnName = "position_id")
    private Position position;
}

@Entity
@Table(name = "position")
public class Position {

    public static final String ID = "id";
    public static final String LATITUDE = "latitude";
    public static final String LONGITUDE = "longitude";
    public static final String BEARING = "bearing";
    public static final String ACCURACY = "accuracy";
    public static final String SPEED = "speed";
    public static final String USER_ID = "user_id";

    @Column(name = ID, unique = true)
    @GenericGenerator(name = "generator", strategy = "foreign",
            parameters = {@org.hibernate.annotations.Parameter(name = "property", value = "user")})
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = LATITUDE)
    private double latitude;

    @Column(name = LONGITUDE)
    private double longitude;

    @Column(name = BEARING)
    private double bearing;

    @Column(name = ACCURACY)
    private double accuracy;

    @Column(name = SPEED)
    private double speed;

    @OneToOne
    @PrimaryKeyJoinColumn
    @Cascade(CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private User user;
}

I'm saving new object into database. Everything is correct except one thing. Fields user_id and position_id are null. Is there any solution which help me do this?

It will take a few steps to fix your problem.

Let's start with that in One to One association there's only one foreign key, you can decide which entity will own the foreign key.

The @joinColumn annotation is supposed to be only in the owning entity, for example, if you decided that user will own the position key as a foreign key then the @joinColumn annotation will be in the user entity under the position field.

on the other entity just use

@OneToOne(mappedby = "the_matching_field_on_the_other entity")

for example:

CREATE TABLE "user"
(
    id INTEGER PRIMARY KEY NOT NULL,
    phone TEXT,
    position_id BIGINT,
    CONSTRAINT user_position_id_fk FOREIGN KEY (position_id) REFERENCES position (id)
);

CREATE TABLE position
(
    id INTEGER PRIMARY KEY NOT NULL,
    latitude DOUBLE PRECISION,
    longitude DOUBLE PRECISION,
    bearing DOUBLE PRECISION,
    accuracy DOUBLE PRECISION,
    speed DOUBLE PRECISION,
);

@Entity
@Table(name = "user")

public class User {

public static final String ID = "id";
public static final String PHONE = "phone";

public User() {
    position = new Position();
}

@Id
@Column(name = ID, unique = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(name = PHONE)
private String phone;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id", referencedColumnName = "position_id")
private Position position;

}

@Entity
@Table(name = "position")
public class Position {

    public static final String ID = "id";
    public static final String LATITUDE = "latitude";
    public static final String LONGITUDE = "longitude";
    public static final String BEARING = "bearing";
    public static final String ACCURACY = "accuracy";
    public static final String SPEED = "speed";
    public static final String USER_ID = "user_id";

    @Column(name = ID, unique = true)
    @GenericGenerator(name = "generator", strategy = "foreign",
            parameters = {@org.hibernate.annotations.Parameter(name = "property", value = "user")})
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = LATITUDE)
    private double latitude;

    @Column(name = LONGITUDE)
    private double longitude;

    @Column(name = BEARING)
    private double bearing;

    @Column(name = ACCURACY)
    private double accuracy;

    @Column(name = SPEED)
    private double speed;

    @OneToOne(mappedBy = "position")
    private User user;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM