简体   繁体   中英

Why hibernate generates unnecessary constraint?

I'm having a strange problem with the SQL generated by a bidirectional relationship in Hibernate. Here's the code.

First the @OneToMany side:

@Entity
@Table(name = "employers")
public class Employer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "eid")
    private Long employerId;
    
    private String name;
    
    @OneToMany(mappedBy = "titleId")
    private Set<Title> titles = new TreeSet<>(); 
    
    // Getters/setters...
}

And the @ManyToOne side:

@Entity
@Table(name = "titles")
public class Title {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "tid")
    private long titleId;
    
    /**
     * Not sure if I need a bi-directional relation here.
     */
    @ManyToOne
    @JoinColumn(name = "employerId")
    private Employer employer;

    // Getters/setters...
}

I'm fairly new to springboot and hibernate, so this is the first thing I've attempted that would actually run. Based on the tutorials and the documentation I've referenced, the SQL generated in my case is wrong.

Here's the generated SQL ( Postgres9Dialect )

CREATE TABLE public.items
(
    item_id bigint NOT NULL DEFAULT nextval('items_item_id_seq'::regclass),
    text character varying(255) COLLATE pg_catalog."default",
    title_tid bigint,
    CONSTRAINT items_pkey PRIMARY KEY (item_id),
    CONSTRAINT fkkwhqrl3vscoqcacws6kgsdlx5 FOREIGN KEY (item_id)
        REFERENCES public.titles (tid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fkluhgxmnakeuroph186b2k05eq FOREIGN KEY (title_tid)
        REFERENCES public.titles (tid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

The problem is this constraint:

CONSTRAINT fkkwhqrl3vscoqcacws6kgsdlx5 FOREIGN KEY (item_id)
REFERENCES public.titles (tid) MATCH SIMPLE
   ON UPDATE NO ACTION
   ON DELETE NO ACTION,

It has the effect of not allowing additional titles from being created if the title id ( tid ) exceeds the highest number of employer ids (eid in the employer table). The generated employers table is correct.

If I delete this constraint manually, then it works as expected.

Why is it creating this erroneous constraint? What am I missing?

(as an aside, title refers to a title one would have for a particular employer, not a book title, so I am not trying to combine employer & author tutorials)

You should correct your mapping in this way:

@Entity
@Table(name = "employers")
public class Employer {
    @OneToMany(mappedBy = "employer")
    private Set<Title> titles = new TreeSet<>(); 
    // ...
}

@Entity
@Table(name = "titles")
public class Title {

    @ManyToOne
    @JoinColumn(name = "employerId")
    private Employer employer;
    // ...
}

The mappedBy should hold the field name of another side of association.

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