Basic IdClass
package org.example.demo.hibernate;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Persistence;
public class Test {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
EntityManager em = factory.createEntityManager();
Login login = new Login();
login.system = "Windows";
login.username = "me";
em.getTransaction().begin();
em.persist(login);
em.getTransaction().commit();
em.clear();
PK pk = new PK();
pk.system = login.system;
pk.username = login.username;
em.find(Login.class, pk);
em.close();
factory.close();
}
@Entity
@IdClass(PK.class)
public static class Login {
@Id
private String system;
@Id
private String username;
Date time = new Date();
}
@SuppressWarnings("serial")
public static class PK implements Serializable {
String system;
String username;
}
}
生成 SQL
drop table if exists Test$Login cascade
create table Test$Login (system varchar(255) not null, username varchar(255) not null, time timestamp, primary key (system, username))
insert into Test$Login (time, system, username) values ('2017-07-01 17:27:19', 'Windows', 'me')
select test_login0_.system as system1_0_0_, test_login0_.username as username2_0_0_, test_login0_.time as time3_0_0_ from Test$Login test_login0_ where test_login0_.system='Windows' and test_login0_.username='me'
IdClass with ManyToOne
package org.example.demo.hibernate;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.ManyToOne;
import javax.persistence.Persistence;
public class Test {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
EntityManager em = factory.createEntityManager();
PK pk = new PK();
pk.system = new System();
pk.system.name = "Windows";
pk.username = "me";
Login login = new Login();
login.system = pk.system;
login.username = pk.username;
em.getTransaction().begin();
em.persist(pk.system);
em.persist(login);
em.getTransaction().commit();
em.clear();
em.find(Login.class, pk);
em.close();
factory.close();
}
@Entity
@IdClass(PK.class)
public static class Login {
@Id
@ManyToOne
private System system;
@Id
private String username;
Date time = new Date();
}
@SuppressWarnings("serial")
public static class PK implements Serializable {
System system;
String username;
}
@Entity
public static class System {
@Id
@GeneratedValue
private Long id;
String name;
}
}
生成 SQL
alter table Test$Login drop constraint FKmla7of81bjip6sejltfgk1ias
drop table if exists Test$Login cascade
drop table if exists Test$System cascade
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start 1 increment 1
create table Test$Login (username varchar(255) not null, time timestamp, system_id int8 not null, primary key (system_id, username))
create table Test$System (id int8 not null, name varchar(255), primary key (id))
alter table Test$Login add constraint FKmla7of81bjip6sejltfgk1ias foreign key (system_id) references Test$System
select nextval ('hibernate_sequence')
insert into Test$System (name, id) values ('Windows', 1)
insert into Test$Login (time, system_id, username) values ('2017-07-01 17:30:36', 1, 'me')
select test_login0_.system_id as system_i3_0_0_, test_login0_.username as username1_0_0_, test_login0_.time as time2_0_0_, test_syste1_.id as id1_1_1_, test_syste1_.name as name2_1_1_ from Test$Login test_login0_ inner join Test$System test_syste1_ on test_login0_.system_id=test_syste1_.id where test_login0_.system_id=1 and test_login0_.username='me'
这种方式与 @EmbeddedId 一样是 non-portably 的
IdClass with partial generation
package org.example.demo.hibernate;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Persistence;
public class Test {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
EntityManager em = factory.createEntityManager();
PK pk = new PK();
pk.username = "me";
Login login = new Login();
login.username = pk.username;
em.getTransaction().begin();
em.persist(login);
em.getTransaction().commit();
em.clear();
pk.uniqueStamp = login.uniqueStamp;
em.find(Login.class, pk);
em.close();
factory.close();
}
@Entity
@IdClass(PK.class)
public static class Login {
@Id
private String username;
@Id
@GeneratedValue
private Integer uniqueStamp;
Date time = new Date();
}
@SuppressWarnings("serial")
public static class PK implements Serializable {
String username;
Integer uniqueStamp;
}
}
生成 SQL
drop table if exists Test$Login cascade
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start 1 increment 1
create table Test$Login (uniqueStamp int4 not null, username varchar(255) not null, time timestamp, primary key (uniqueStamp, username))
select nextval ('hibernate_sequence')
insert into Test$Login (time, uniqueStamp, username) values ('2017-07-01 17:37:50', 1, 'me')
select test_login0_.uniqueStamp as uniqueSt1_0_0_, test_login0_.username as username2_0_0_, test_login0_.time as time3_0_0_ from Test$Login test_login0_ where test_login0_.uniqueStamp=1 and test_login0_.username='me'
Use of this feature may or may not be portable from a JPA perspective.