복붙노트

[SQL] 최대 절전 모드 문제 : 외래 키 컬럼의 수가 같아야 기본 키를 참조로

SQL

최대 절전 모드 문제 : 외래 키 컬럼의 수가 같아야 기본 키를 참조로

목표 : 나는 그런 우리가 다음 importJobId을하고 할당이있을 수 없습니다 작업없이으로 만 우리가 할당에서 ID를 가질 수 있습니다 때 할당 테이블의 ID에 대한 외래 키로 ImportJob에 importJobId을 갖고 싶어.

ImportJob 테이블 [ORGID, IMPORTJOBTYPE] 등 복합 기본 키를 가지고 있으며 사용하여 최대 절전 모드에서 외래 키 관계를 만들려고 노력하고 있어요

  <id name="id"
        column="ID">
        <generator class="native"/>
    </id>
    <many-to-one name="importjobid"
                 class="com.delta.pdo.admin.ImportJob"
                 cascade="save-update"/>

Allocation.hbm.xml에서 작동하지 않는 등의 오류 메시지가 무엇입니까 :

Foreign key (FKB29B5F7366007086:ALLOCATIONS [importjobid])) 
must have same number of columns as the 
referenced primary key (IMPORTJOBMANAGMENT [ORGID,IMPORTJOBTYPE])

여기 내 ImportJob.hbm.xml 파일입니다

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.delta.pdo.admin.ImportJob" table="IMPORTJOB" lazy="false">
        <!-- we don't cache this since the commissions code is too screwed up to work with -->
        <composite-id>
            <key-property name="orgId" type="long" column="ORGID"/>
            <key-property name="importJobType" type="java.lang.String" column="IMPORTJOBTYPE"/>
        </composite-id>

        <!-- Make sure importjobid is not-null='true '-->
        <property name="importjobid" type="long" column="IMPORTJOBID" />
        <property name="allocations" type="boolean" column="ALLOCATIONS" />
    </class>
</hibernate-mapping>

여기에 참조 할 수 있도록 빈 클래스는 다음과 같습니다

public class AllocationBean extends WorkbenchBeanBase
{
    private static final Logger log = Logger.getLogger(AllocationBean.class);
    private Float allocations;
    private String importJobType;
    private long id;
    private long orgId;
}

public class ImportJobManagment implements Serializable
{
    private long importjobid;
    private long orgId;
    private String importJobType;
    private boolean allocations = false;
}

나는 단순함을 위해 제거 게터 / 세터 있습니다.

업데이트 : 1 방법은 내가하지 않도록 우리가 복합 다른 테이블의 키하지만의에 키가 외국 단일 열을이 작업을 수행하고있을 수있는 경우입니다, orgId 및 importJobType의 복합 키에 대한 외래 키 참조가 하나 개의 테이블에서 id 컬럼을 가지고, 지금 설정입니다 내 유스 케이스.

업데이트 : 2

멋진 세부 사항에 대한 감사합니다, 이것은 확실히 외래 키 구현의 내 지식을 enchance 것이다 그러나 나의 최종 목표는 하나 테이블 A는 해당 테이블과 테이블 B에 고유 행을 식별하기위한 복합 키가 두 테이블 사이에 하나의 매핑, 내가 원하는 우리는 테이블 A의 항목이있는 경우 다음 같은 작업 ID 항목이 표 B에 있어야 있도록 테이블 A에 대한 외래 키 참조를 할 것이다 기본 키가, 지금은 우리가 참조 할 테이블 B의 단일 열 기본 키를 가질 수 없습니다 당신의 요점을 파악 표 A. 복합 키

그래서 기본적으로 내가 표 A는이 복합 기본 키와 테이블 B를 가지고 테이블 사이에 하나의 매핑에 하나를 갖고 싶어 당연히이 언급 한 오류가 발생하고 있고 그래서 지금 내가 테이블에 복합 키를 만들려고하고있다 최대 절전 모드를 사용하여 단일 열 기본 키, B는 이제 테이블 A에 대한 외래 키 참조를 만들어, 나는 세부 사항 입력에 대한 나중에 다시 감사를 확인하고 내 결과 내 질문을 업데이트합니다.

해결법

  1. ==============================

    1.이 오류는 복합 기본 키를 참조하기 위해, 당신은 복합 외부 키가 필요, 자체 말한다. (- 당신은 아마 단지 1 열이 고유 키를 참조 할 수 없습니다 복합 기본 키 상태 당신은 키를 만들기 위해이 개 분야의 고유 한 조합을 필요.)

    이 오류는 복합 기본 키를 참조하기 위해, 당신은 복합 외부 키가 필요, 자체 말한다. (- 당신은 아마 단지 1 열이 고유 키를 참조 할 수 없습니다 복합 기본 키 상태 당신은 키를 만들기 위해이 개 분야의 고유 한 조합을 필요.)

    이것은 XML 매핑 파일을 사용하여 달성하는 방법에 관해서는 나는 물론, 대부분의 사람들은 요즘 주석을 사용하지거야 ..

    자바 클래스에 관해서는, 나는, ImportJobManagement는 ImportJob을 보유하고 있으리라 믿고있어 그래서 그 클래스는 ID를 참조하지 않아야하지만,이 같은 개체 자체 :

    public class ImportJobManagment implements Serializable {
        private ImportJob importJob;
        ...
    }
    

    자바 클래스는 다른 클래스를 참조하고, 복합 키가 아닌 회원한다 - 그것은 자바 멤버 변수에 복합 키에서 매핑 매핑까지입니다.

    갱신에 답변 :

    짧은 대답은 당신이 할 수없는, 아니 없다. 외래 키 작동 방법은, 당신이 테이블의 특정 행을 참조 할 수 있습니다. 그리고, 특정 행을 참조하십시오하기 위해, 당신은 정체성, 하나의 행을 설명하는 것이 무엇인가, 그리고 다른이 필요합니다. SQL에서, 즉 고유 키를이를 달성하기위한 구조가있다. 열 (또는 열 복합)이 고유 알리는으로이 값을 전체 테이블에 1 행의 최대있을 것이다, 그 / 그들의 결합 값은 고유 것을 알고, 다른 어떤 제약 조건 위반이 될 것이다 .

    따라서, 외래 키는 하나의 고유 한 제약 열 또는 여러 열을 걸친 복합 고유의 키 중 하나를 의미합니다. 모든 테이블이 이미 고유 키를 가지고 있기 때문에, (항상 고유) 기본 키,이 외래 키 참조를 사용하는 것이 일반적이지만, 어떤 unqiue 열이 작동합니다.

    우리가 단일 열 고유 키와 테이블을 참조 할 때 가장 쉬운 경우이다. 두 간단한 테이블 이러한 A. 인스턴스의 'ID'열에 대한 외부 키를 갖는 단일 열 'ID'및 B,에 'ID'항목을 보유하고 있지만, 또 다른 칼럼, A_ID를 보유하고, 상황이 될 수있다 :

    A:
    | id | 
    |----|
    |  1 |
    |  2 |
    |  3 |
    
    B:
    | id | a_id |
    | 2  |  3   |
    | 3  |  1   |
    

    여기서, B 기준 각 행 A. 그 행에서 직접 참조 직접에 값 'ID'항목을 테이블 B에 대응한다 A_ID의 값. ID (3)와, 등등의 A 참조 번호 2와 B 그래서.

    이제 복합 고유 키가있는 테이블을 참조하는 방법을 살펴 수 있습니다. 우리의 예를 유지할 수 있습니다,하지만 지금 A는 함께 'ID'로 복합 기본 키를 구성하는 다른 열 'sec_id'를 가지고있다.

    A:
    | id | sec_id |
    |----|--------|
    | 1  |   3    |
    | 3  |   1    |
    | 3  |   7    |
    
    B:
    | id | a_id |
    |----|------|
    | 2  |  3   |
    

    외래 키가 참조가,이 명확하게 일을하지 않는 테이블에 단일 행을 참조해야하기 때문에이 상황에서, 우리는 B.에 문제가 있습니다. A의 어느 행의 값이 '3'을 수행 표현? 첫 번째 행의 sec_id? ID의 두 번째 또는 세 번째 (단,이 경우, 어느 하나?에서)? 대답은 그냥이 없습니다 SQL하며,이 단일 행을 참조하는 B에 충분한 정보가없는, 물론 둘의 없다. 이러한 외래 키를 추가하는 것은 따라서 허용되지 않습니다.

    ID ','sec_id ''A의 단일 행 (의 독특한 조합에 의해 식별되기 때문에, 열의 기준 A와 B의 순서에서는, 양쪽의 'id' 열 및의'sec_id 참조 필요 ) 쌍. B는 다음과 같이 찾고 그래서 :

    | id | a_id | a_sec_id |
    |----|------|----------|
    | 1  |  1   |     3    |
    | 2  |  3   |     1    |
    | 3  |  3   |     7    |
    

    지금, B는 단일 행을 참조 할 수있는 충분한 정보를 보유하고, 데이터 방송, 그것은한다.

    다시 업데이트 :

    나는 현재 JPA 인증을 읽고 있어요, 그리고 복합 키 매핑에 대한 장에 도달했습니다. 복합 기본 키를 매핑하기 위해, 당신은 당신의 키의 속성을 매핑하는 기본 키 클래스가 필요합니다. 그 일을 두 가지 방법, 키 속성이 아니라 개체 자체에 매핑되어야 하나, 그리고 그것은 임베디드 키로서 사용되는 일이 있습니다.

    내가 코드 예제를 제공 할 것이다, 그들은 꽤 (이, 당신이 정말로뿐만 아니라 그렇게해야 주석을 사용합니다.) 자신에 대한 이야기

    첫 번째 예는 일반 클래스 ID와 기본 예이다 (포함하지 않음). 여기, 우리는 기본 키가 정수 ID와 국가로 구성되는 직원 엔티티가 (이 명 직원은 다른 나라의 경우 동일한 ID를 가질 수있다).

    @Entity
    @IdClass(EmployeeId.class)
    public class Employee {
        @Id private String country
        @Id
        @Column(name = "EMP_ID")
        private int id;
        private String name;
        ...
    }
    
    public class EmployeeId implements Serializable {
        private String country;
        private int id;
    
        public EmployeeId() { }
        public EmployeeId(final String country, final int id) {
            this.country = country;
            this.id = id;
        }
    
        //getters for the properties
    
        public boolean equals(final Object other) {
        //must be implemented
        }
    
        public int hashCode() {
        //must be implemented
        }
    }
    

    노트 :

    이 작업을 수행 할 수있는 다른 방법은 임베디드 ID-클래스를 통해입니다 :

    @Entity
    public class Employee {
        @EmbeddedId
        private EmployeeId id;
        private String name;
    
        public Employee(final String country, final int id) {
            this.id = new EmployeeId(country, id);
        }
    
        public String getCountry() {
            return id.getCountry();
        }
    }   
    
    @Embeddable
    public class EmployeeId {
       private String country;
       @Column(name = "EMP_ID")
       private int id;
    
       //constructor + getters + equals +hashCode
    }
    

    노트 :

    나는 후자와 같은 자사의 컴팩트하고 중복을 포함하지 않는,하지만 두 가지를 사용하는 방법을 다시 모르겠다는 비교 나은 때문에 ..

  2. ==============================

    2.ImportJob.hbm.xml

    ImportJob.hbm.xml

    이 하나 개 추가 삽입을 사용하여 우는 소리처럼 importjobid하는 거짓 =

    <property name="importjobid" type="long" 
        column="importjobid" type="long" insert="false"/>
    
  3. from https://stackoverflow.com/questions/14510547/hibernate-issue-foreign-key-must-have-same-number-of-columns-as-referenced-pri by cc-by-sa and MIT license