package org.example.demo.hibernate;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Persistence;
import org.hibernate.annotations.NaturalId;
public class Test {
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();
        Person p = new Person();
        Address a = new Address();
        PersonAddress pa = new PersonAddress();
        pa.person = p;
        pa.address = a;
        em.getTransaction().begin();
        em.persist(p);
        em.persist(a);
        em.persist(pa);
        em.getTransaction().commit();
        em.clear();
        PersonAddress pk = new PersonAddress();
        pk.person = p;
        pk.address = a;
        em.find(PersonAddress.class, pk);
        em.close();
        factory.close();
    }
    @Entity
    public static class PersonAddress implements Serializable {
        @Id
        @ManyToOne
        private Person person;
        @Id
        @ManyToOne()
        private Address address;
    }
    @Entity
    public static class Person {
        @Id
        @GeneratedValue
        private Long id;
        @NaturalId
        private String registrationNumber;
    }
    @Entity
    public static class Address {
        @Id
        @GeneratedValue
        private Long id;
        String street;
        String number;
        String postalCode;
    }
}
生成 SQL
alter table Test$PersonAddress drop constraint FKfs7lmpqjsls2706er44lpttj7
alter table Test$PersonAddress drop constraint FKk2gfifj5lnjaflrtsf15c4pq5
drop table if exists Test$Address cascade
drop table if exists Test$Person cascade
drop table if exists Test$PersonAddress cascade
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start 1 increment 1
create table Test$Address (id int8 not null, number varchar(255), postalCode varchar(255), street varchar(255), primary key (id))
create table Test$Person (id int8 not null, registrationNumber varchar(255), primary key (id))
create table Test$PersonAddress (person_id int8 not null, address_id int8 not null, primary key (person_id, address_id))
alter table Test$Person add constraint UK_4yxxld4ccjh8fxhwo8g12nms2 unique (registrationNumber)
alter table Test$PersonAddress add constraint FKfs7lmpqjsls2706er44lpttj7 foreign key (person_id) references Test$Person
alter table Test$PersonAddress add constraint FKk2gfifj5lnjaflrtsf15c4pq5 foreign key (address_id) references Test$Address
select nextval ('hibernate_sequence')
select nextval ('hibernate_sequence')
insert into Test$Person (registrationNumber, id) values (NULL, 1)
insert into Test$Address (number, postalCode, street, id) values (NULL, NULL, NULL, 2)
insert into Test$PersonAddress (person_id, address_id) values (1, 2)
select test_perso0_.person_id as person_i1_2_0_, test_perso0_.address_id as address_2_2_0_, test_perso1_.id as id1_1_1_, test_perso1_.registrationNumber as registra2_1_1_, test_addre2_.id as id1_0_2_, test_addre2_.number as number2_0_2_, test_addre2_.postalCode as postalCo3_0_2_, test_addre2_.street as street4_0_2_ from Test$PersonAddress test_perso0_ inner join Test$Person test_perso1_ on test_perso0_.person_id=test_perso1_.id inner join Test$Address test_addre2_ on test_perso0_.address_id=test_addre2_.id where test_perso0_.person_id=1 and test_perso0_.address_id=2
注意 PersonAddress 必须 implements Serializable 否则抛异常 org.hibernate.MappingException: Composite-id class must implement Serializable: org.example.demo.hibernate.Test$PersonAddress