Столбцы, образующие составной ключ в одной таблице, фактически находятся в другой таблице как класс сущности с записью внешнего ключа - PullRequest
0 голосов
/ 19 ноября 2018

Таблица отраслевых кодов

Industry_Code(Primary key) | Industry_name
1| Reliance
2| TaTa

Таблица технологических_кодов

Technology_code(Primary Key) | technology name
81| java
81|cpp

коды_хозяйств Таблица

Industry_Code(Primary key)(Foreign Key to Industry_Codes table) | technology_code(pk)(Foreign key to Technology_Code table) | other fields

1 | 81 |
2| 81|
1| 82

Регистрация

Mobile Number(Pk)|Industry_code(Fk to carrier_codes) |Technology_Code(Fk to carrier_codes)

12345|1|83
78913|1|88

для данной структуры таблицы класс сущности записывается как-

@Entity
@Table(name = "Industry_Codes")
public class IndustryCodes implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="TELECOM_INDUSTRY_CODE")
    private String telecomIndustryCode;

    @Column(name="INdustry_Name")
    private String Industry_Name;

}

Таблица 2

@Entity
@Table(name="Technology_Codes")
public class TechnologyCodes {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "Technology_code")
    private int targetTechnologyCode;

    @Column(name="Technology_Name")
    private String TechnologyName;
}

и

@Entity
@Table(name = "CARRIER_CODES")
public class CarrierCodes {
    private static final long serialVersionUID = 1L;

    @Id
    @ManyToOne
    @JoinColumn(name ="CARRIER_CODE",referencedColumnName="INDUSTRY_CODE")
    private IndustryCodes carrierCode;

    @Id
    @ManyToOne
    @JoinColumn(name ="TECHNOLOGY_CODE",referencedColumnName="TECHNOLOGY_CODE")
    private TechnologyCodes TechnologyCode;

}

Теперь я все потерялся в том, как записать сущность для таблицы Register, в которой есть столбец, такой как carrier_code и technology_code, оба они являются внешним ключом для таблицы carrier_codes, и оба они вместе образуют составной ключ для таблицы carrier_codes, также существует множество случаев появления обоих. поле в обеих таблицах, таким образом, связь многих ко многим между двумя столбцами обеих таблиц.

Любая помощь в написании регистрационного лица приветствуется. Я совершенно новичок в ассоциациях в JPA.

1 Ответ

0 голосов
/ 20 ноября 2018

Во-первых, убедитесь, что вы понимаете отношения.UML и изображения - ваш друг.

enter image description here

Обратите внимание, что 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
...