Во-первых, убедитесь, что вы понимаете отношения.UML и изображения - ваш друг.
Обратите внимание, что IndustryCode
и TechCode
- это отношения ManyToMany.В DDL связь «многие ко многим» осуществляется с помощью таблицы соединений и составного ключа.В JPA это обычно просто отображается с аннотацией ManyToMany
, но так как вы также хотите использовать его в качестве внешнего ключа для таблицы Registry
, вы должны определить сущность самостоятельно.Это сделано с CarrierCodes
.В JPA EmbeddableId
, как правило, является самым простым способом создания составного ключа для объекта, который будет использоваться таким образом.Таким образом, JPA можно сделать так:
@Entity
public class IndustryCode {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String industryName;
@OneToMany(mappedBy="industryCode")
private Set<CarrierCodes> industryCodes;
@Entity
public class TechCode {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String techName;
@OneToMany(mappedBy="techCode")
private Set<CarrierCodes> techCodes;
@Entity
public class CarrierCodes {
@EmbeddedId
private CarrierCodesId id = new CarrierCodesId();
@ManyToOne
@MapsId("techCodeId")
private TechCode techCode;
@ManyToOne
@MapsId("industryCodeId")
private IndustryCode industryCode;
@SuppressWarnings("serial")
@Embeddable
public class CarrierCodesId implements Serializable {
private Long industryCodeId;
private Long techCodeId;
@Entity
public class Register {
@Id
private Long mobileNumber;
@ManyToOne
// optional but nice to have consistent names
@JoinColumns({
@JoinColumn(name="industryCode_id", referencedColumnName="industryCode_id"),
@JoinColumn(name="techCode_id", referencedColumnName="techCode_id")
})
private CarrierCodes carrierCodes;
И использовать его аналогично вашему примеру - вот так.
tx.begin();
IndustryCode ic1 = new IndustryCode("Reliance");
IndustryCode ic2 = new IndustryCode("TaTa");
TechCode tc1 = new TechCode("java");
TechCode tc2 = new TechCode("cpp");
CarrierCodes cc1 = new CarrierCodes(tc1, ic1);
CarrierCodes cc2 = new CarrierCodes(tc1, ic2);
CarrierCodes cc3 = new CarrierCodes(tc2, ic1);
Register r1 = new Register(12345L, cc1);
Register r2 = new Register(78913L, cc2);
em.persist(ic1);
em.persist(ic2);
em.persist(tc1);
em.persist(tc2);
em.persist(cc1);
em.persist(cc2);
em.persist(cc3);
em.persist(r1);
em.persist(r2);
tx.commit();
em.clear();
List<Register> rs = em.createQuery("select r from Register r left outer join fetch r.carrierCodes cc where cc.techCode.techName = 'java'", Register.class).getResultList();
rs.stream().forEach(r->System.out.println(r.getMobileNumber() + " " + r.getCarrierCodes().getTechCode().getTechName()));
List<Register> rs2 = em.createQuery("select r from Register r left outer join fetch r.carrierCodes cc where cc.industryCode.industryName = 'TaTa'", Register.class).getResultList();
rs2.stream().forEach(r->System.out.println(r.getMobileNumber() + " " + r.getCarrierCodes().getIndustryCode().getIndustryName()));
Это дает мне следующий вывод.
Hibernate: create table CarrierCodes (industryCode_id bigint not null, techCode_id bigint not null, primary key (industryCode_id, techCode_id))
Hibernate: create table IndustryCode (id bigint generated by default as identity (start with 1), industryName varchar(255), primary key (id))
Hibernate: create table Register (mobileNumber bigint not null, industryCode_id bigint, techCode_id bigint, primary key (mobileNumber))
Hibernate: create table TechCode (id bigint generated by default as identity (start with 1), techName varchar(255), primary key (id))
Hibernate: alter table CarrierCodes add constraint FKfq42ix66txvd15crq2pey3dcp foreign key (industryCode_id) references IndustryCode
Hibernate: alter table CarrierCodes add constraint FK9os97pd53ijerp2mibllknovn foreign key (techCode_id) references TechCode
Hibernate: alter table Register add constraint FK2k626ouo1ajsccqlpb5y3xa8u foreign key (industryCode_id, techCode_id) references CarrierCodes
Hibernate: insert into IndustryCode (id, industryName) values (default, ?)
Hibernate: insert into IndustryCode (id, industryName) values (default, ?)
Hibernate: insert into TechCode (id, techName) values (default, ?)
Hibernate: insert into TechCode (id, techName) values (default, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into Register (industryCode_id, techCode_id, mobileNumber) values (?, ?, ?)
Hibernate: insert into Register (industryCode_id, techCode_id, mobileNumber) values (?, ?, ?)
Hibernate: select register0_.mobileNumber as mobileNu1_2_0_, carriercod1_.industryCode_id as industry1_0_1_, carriercod1_.techCode_id as techCode2_0_1_, register0_.industryCode_id as industry2_2_0_, register0_.techCode_id as techCode3_2_0_ from Register register0_ left outer join CarrierCodes carriercod1_ on register0_.industryCode_id=carriercod1_.industryCode_id and register0_.techCode_id=carriercod1_.techCode_id cross join TechCode techcode2_ where carriercod1_.techCode_id=techcode2_.id and techcode2_.techName='java'
Hibernate: select industryco0_.id as id1_1_0_, industryco0_.industryName as industry2_1_0_ from IndustryCode industryco0_ where industryco0_.id=?
Hibernate: select techcode0_.id as id1_3_0_, techcode0_.techName as techName2_3_0_ from TechCode techcode0_ where techcode0_.id=?
Hibernate: select industryco0_.id as id1_1_0_, industryco0_.industryName as industry2_1_0_ from IndustryCode industryco0_ where industryco0_.id=?
12345 java
78913 java
Hibernate: select register0_.mobileNumber as mobileNu1_2_0_, carriercod1_.industryCode_id as industry1_0_1_, carriercod1_.techCode_id as techCode2_0_1_, register0_.industryCode_id as industry2_2_0_, register0_.techCode_id as techCode3_2_0_ from Register register0_ left outer join CarrierCodes carriercod1_ on register0_.industryCode_id=carriercod1_.industryCode_id and register0_.techCode_id=carriercod1_.techCode_id cross join IndustryCode industryco2_ where carriercod1_.industryCode_id=industryco2_.id and industryco2_.industryName='TaTa'
78913 TaTa