JPA加入两个辅助表

时间:2012-08-30 20:24:40

标签: java hibernate jpa spring-data-jpa

我有这五张桌子:

REF_CT          REF_CT_L        REF_ST        REF_ST_L
======          ========        ======        ========
CT_ID           CT_ID           ST_ID         ST_ID
ST_ID           LANGUAGE_ID     NAME          LANGUAGE_ID
NAME            NAME            REF_CODE      NAME
REF_CODE        DESCRIPTION                   DESCRIPTION


REF_LANGUAGE
============
LANGUAGE_ID
LOCALE_CODE
NAME

通过使用JPA,我创建了这三个实体类:

  1. Class common.contact.City

    @Entity
    @Table(name = "REF_CT")
    @SecondaryTable(name = "REF_CT_L")
    public class City implements Reference {
       @Id
       @Column(name = "CT_ID")
       @TableGenerator(name = "TABLE_GEN", table = "SYS_SEQ",
            pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_VALUE", pkColumnValue =   "CITY_SEQ")
       @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
       private Integer id;
    
       @Column(name = "NAME")
       private String name;
    
       @Column(table = "REF_CT_L", name = "NAME")
       private String value;
    
       @Column(name = "REF_CODE")
       private String refCode;
    
       @ManyToOne(targetEntity = Language.class)
       @JoinColumn(table = "REF_CT_L", name = "LANGUAGE_ID")
       private Language language;
    
       @ManyToOne(targetEntity = State.class, optional = true)
       @JoinColumn(name = "ST_ID", referencedColumnName = "ST_ID")
       private State state;
    
  2. Class common.contact.State

    @Entity
    @Table(name = "REF_ST")
    @SecondaryTable(name = "REF_ST_L")
    public class State implements Reference {
       @Id
       @Column(name = "ST_ID")
       @TableGenerator(name = "TABLE_GEN", table = "SYS_SEQ",
            pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_VALUE", pkColumnValue = "STATE_SEQ")
       @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
       private Integer id;
    
       @Column(name = "NAME")
       private String name;
    
       @Column(table = "REF_ST_L", name = "NAME")
       private String value;
    
       @Column(name = "REF_CODE")
       private String refCode;
    
       @OneToMany(targetEntity = City.class, mappedBy = "state")
       private Set<City> cities;
    
       @ManyToOne(targetEntity = Language.class)
       @JoinColumn(table = "REF_ST_L", name = "LANGUAGE_ID", unique = true, referencedColumnName = "LANGUAGE_ID")
       private Language language;
    
  3. Class common.system.Language

    @Entity
    @Table(name = "SYS_LANGUAGE")
    public class Language implements BaseEntity {
       @Id
       @Column(name = "LANGUAGE_ID")
       @TableGenerator(name = "TABLE_GEN", table = "SYS_SEQ",
            pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_VALUE", pkColumnValue = "LANGUAGE_SEQ")
       @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
       private Integer id;
    
       @Column(name = "LOCALE_CODE")
       private String locale;
    
       @Column(name = "NAME")
       private String name;
    
  4. 但是当我尝试运行此查询时

    select city from City city where city.id = 1 
    

    我收到了这个错误:

    org.hibernate.HibernateException: More than one row with the given identifier was found: 10, for class: common.contact.State
    

    仅供参考,增加了以下数据:

    REF_CT

    CT_ID    ST_ID    NAME    REF_CODE
    =====    =====    ====    ========
      1        10    CHERAS     CHE
    

    REF_CT_L

    CT_ID    LANGUAGE_ID    NAME       DESCRIPTION
    =====    ===========    ====       ===========
      1           1      BANDAR CHERAS  CHERAS BARU
      1           2      CHERAS TOWN    NEW CHERAS  
    

    REF_ST

    ST_ID    NAME     REF_CODE
    =====    ====     ========
      10    SELANGOR    SEL
    

    REF_ST_L

    ST_ID    LANGUAGE_ID     NAME      DESCRIPTION
    =====    ===========     ====      ===========
      10          1        SELANGOR    SELANGOR BARU
      10          2        SERIANGOR   NEW SERIANGOR
    

    REF_LANGUAGE

    LANGUAGE_ID    LOCALE_CODE    NAME
    ===========    ===========    ====
         1           ms_En       Malay
         2           en_US       English
    

    生成的SQL是:

    SELECT state0_.st_id AS st1_50_0_,
           state0_.NAME AS name50_0_, state0_.ref_code AS ref4_50_0_,
           state0_1_.language_id AS language2_51_0_, state0_1_.NAME AS name51_0_
      FROM ref_st state0_ LEFT OUTER JOIN ref_st_l state0_1_
           ON state0_.st_id = state0_1_.st_id
     WHERE state0_.st_id = 10;
    

    感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您的代码正在生成LEFT JOIN,因为您设置了City - &gt;状态关系可选。将它更改为不可为空,你应该得到一个内连接,它应该解决返回的多行。

common.contact.City - &gt;

@ManyToOne(targetEntity = State.class, optional = false)
@JoinColumn(name = "ST_ID", referencedColumnName = "ST_ID", nullable = false)
private State state;

答案 1 :(得分:0)

“REF_ST”与“REF_ST_L”具有一对多的关系。这意味着“REF_ST_L”不能映射为辅助表(这意味着一对一的关系)。

相同的逻辑对“REF_CT”有效 - &gt; “REF_CT_L”。