2012-11-21 3 views
2

복합 기본 키가있는 최대 절전 모드 집합에 문제가 있습니다.최대 절전 모드 합성 기본 키

우리는 "목표"라는 개념을 가지고 있습니다. 대상 ID는 세 개의 다른 테이블 (엔티티) 기본 ID의 조합이어야합니다. 대상에는 int 태그가 있습니다. 직원은 표적 집합을 가져야합니다.

CREATE TABLE IF NOT EXISTS `target` (
    `role_id` bigint(20) NOT NULL, 
    `ApplicationPeriod_id` bigint(20) NOT NULL, 
    `project_class_id` bigint(20) NOT NULL, 
    `target` int(11) NOT NULL, 
    PRIMARY KEY (`role_id`,`ApplicationPeriod_id`,`project_class_id`), 
    KEY `fk_role_id` (`role_id`), 
    KEY `fk_ApplicationPeriod_id` (`ApplicationPeriod_id`), 
    KEY `fk_project_class_id` (`project_class_id`), 
    KEY `FKCB7E71918717386C` (`project_class_id`), 
    KEY `FKCB7E7191BEC322C1` (`ApplicationPeriod_id`), 
    KEY `FKCB7E71917B617197` (`role_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

이 SQL은 잘 작동하고는 오랫동안 applicationperiodid 및 projectclassid이 다르기으로 ROLE_ID (직원) 당 둘 이상의 대상에 나를 수 있습니다 다음 SQL은 다음과 같습니다.

이 대상 클래스

@Entity 
@Table(name = "target") 
@AssociationOverrides({ 
     @AssociationOverride(name = "targetId.employee", 
      joinColumns = @JoinColumn(name = "role_id")), 
     @AssociationOverride(name = "targetId.applicationPeriod", 
      joinColumns = @JoinColumn(name = "ApplicationPeriod_id")), 
     @AssociationOverride(name = "targetId.projectClass", 
       joinColumns = @JoinColumn(name = "project_class_id")) 
}) 
public class Target implements Serializable { 

    @EmbeddedId 
    private TargetId targetId; 

    private int target; 

    public TargetId getTargetId() { 
     return targetId; 
    } 

    public void setTargetId(TargetId targetId) { 
     this.targetId = targetId; 
    } 

    public int getTarget() { 
     return target; 
    } 

    public void setTarget(int target) { 
     this.target = target; 
    } 

    public Target() { 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof Target)) return false; 

     Target target = (Target) o; 

     if (this.target != target.target) return false; 
     if (targetId != null ? !targetId.equals(target.targetId) : target.targetId != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = targetId != null ? targetId.hashCode() : 0; 
     result = 31 * result + target; 
     return result; 
    } 
} 

이 내가 각 직원의 대상 세트를 저장할 직원 클래스를,이다 인 TARGETID 클래스

@Embeddable 
public class TargetId implements Serializable { 

    @ManyToOne 
    private Employee employee; 

    @ManyToOne 
    private ApplicationPeriod applicationPeriod; 

    @ManyToOne 
    private ProjectClass projectClass; 


    public Employee getEmployee() { 
     return employee; 
    } 

    public void setEmployee(Employee employee) { 
     this.employee = employee; 
    } 

    public ApplicationPeriod getApplicationPeriod() { 
     return applicationPeriod; 
    } 

    public void setApplicationPeriod(ApplicationPeriod applicationPeriod) { 
     this.applicationPeriod = applicationPeriod; 
    } 

    public ProjectClass getProjectClass() { 
     return projectClass; 
    } 

    public void setProjectClass(ProjectClass projectClass) { 
     this.projectClass = projectClass; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof TargetId)) return false; 

     TargetId that = (TargetId) o; 

     if (applicationPeriod != null ? !applicationPeriod.equals(that.applicationPeriod) : that.applicationPeriod != null) 
      return false; 
     if (employee != null ? !employee.equals(that.employee) : that.employee != null) return false; 
     if (projectClass != null ? !projectClass.equals(that.projectClass) : that.projectClass != null) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = employee != null ? employee.hashCode() : 0; 
     result = 31 * result + (applicationPeriod != null ? applicationPeriod.hashCode() : 0); 
     result = 31 * result + (projectClass != null ? projectClass.hashCode() : 0); 
     return result; 
    } 
} 

입니다.

@Entity 
@Cacheable(true) 
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific 
public class Employee { 

    ... 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "targetId.employee", cascade=CascadeType.ALL, orphanRemoval=true) 
    private Set<Target> targets = new HashSet<Target>(); 

    public Set<Target> getTargets() { 
     return targets; 
    } 

    public void setTargets(Set<Target> targets) { 
     this.targets = targets; 
    } 

    ... 

} 

최대 절전 모드 작업을 통해 대상을 만들고 저장하면 데이터베이스의 모든 것이 잘 보입니다. 문제는 심지어 applicationperiod와 projectclass가 다르면 데이터베이스가 employee 당 하나 이상의 target을 저장할 수 있다고 생각한다. Hibernate는 applicationperiod와 projectclass가 다른지 여부에 관계없이 employee 당 하나 이상의 target을 저장하지 않을 것이다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? Hibernate로 하여금 한 명당 하나 이상의 타겟을 저장할 수있게하려면 어떻게해야합니까?

답변

5

좋아요, 알아 냈습니다. 문제는 TargetID 클래스가 Entity 특성을 사용할 수 없으며, 문제의 엔티티에 대한 ID를 가리 키기 위해 Longs를 사용해야한다는 것입니다. 그런 다음 SQL을 사용하여 DB의 열 사이에 올바른 제약 조건과 연결을 설정합니다.

SQL :

CREATE TABLE IF NOT EXISTS `target` (
    `applicationPeriodId` bigint(20) NOT NULL, 
    `employeeId` bigint(20) NOT NULL, 
    `projectClassId` bigint(20) NOT NULL, 
    `target` int(11) NOT NULL, 
    PRIMARY KEY (`applicationPeriodId`,`employeeId`,`projectClassId`), 
    KEY `FKCB7E71913353DC5C` (`employeeId`), 
    KEY `FKCB7E7191A520201E` (`projectClassId`), 
    KEY `FKCB7E7191790761A4` (`applicationPeriodId`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

-- 
-- Constraints for table `target` 
-- 
ALTER TABLE `target` 
    ADD CONSTRAINT `FKCB7E7191790761A4` FOREIGN KEY (`applicationPeriodId`) REFERENCES `ApplicationPeriod` (`id`), 
    ADD CONSTRAINT `FKCB7E71913353DC5C` FOREIGN KEY (`employeeId`) REFERENCES `role` (`id`), 
    ADD CONSTRAINT `FKCB7E7191A520201E` FOREIGN KEY (`projectClassId`) REFERENCES `project_class` (`id`); 

복합 ID 클래스 :

@Embeddable 
public class TargetId implements Serializable { 

    @Basic 
    private Long employeeId; 

    @Basic 
    private Long applicationPeriodId; 

    @Basic 
    private Long projectClassId; 

    public Long getEmployeeId() { 
     return employeeId; 
    } 

    public void setEmployeeId(Long employeeId) { 
     this.employeeId = employeeId; 
    } 

    public Long getApplicationPeriodId() { 
     return applicationPeriodId; 
    } 

    public void setApplicationPeriodId(Long applicationPeriodId) { 
     this.applicationPeriodId = applicationPeriodId; 
    } 

    public Long getProjectClassId() { 
     return projectClassId; 
    } 

    public void setProjectClassId(Long projectClassId) { 
     this.projectClassId = projectClassId; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof TargetId)) return false; 

     TargetId targetId = (TargetId) o; 

     if (applicationPeriodId != null ? !applicationPeriodId.equals(targetId.applicationPeriodId) : targetId.applicationPeriodId != null) 
      return false; 
     if (employeeId != null ? !employeeId.equals(targetId.employeeId) : targetId.employeeId != null) return false; 
     if (projectClassId != null ? !projectClassId.equals(targetId.projectClassId) : targetId.projectClassId != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = employeeId != null ? employeeId.hashCode() : 0; 
     result = 31 * result + (applicationPeriodId != null ? applicationPeriodId.hashCode() : 0); 
     result = 31 * result + (projectClassId != null ? projectClassId.hashCode() : 0); 
     return result; 
    } 
} 

[대상 엔티티 :

@Entity 
@Table(name = "target") 
@AssociationOverrides({ 
     @AssociationOverride(name = "targetId.employeeId", 
      joinColumns = @JoinColumn(name = "role_id")), 
     @AssociationOverride(name = "targetId.applicationPeriodId", 
      joinColumns = @JoinColumn(name = "ApplicationPeriod_id")), 
     @AssociationOverride(name = "targetId.projectClassId", 
       joinColumns = @JoinColumn(name = "project_class_id")) 
}) 
public class Target implements Serializable { 

    @EmbeddedId 
    private TargetId targetId; 

    private int target; 

    public TargetId getTargetId() { 
     return targetId; 
    } 

    public void setTargetId(TargetId targetId) { 
     this.targetId = targetId; 
    } 

    public int getTarget() { 
     return target; 
    } 

    public void setTarget(int target) { 
     this.target = target; 
    } 

    public Target() { 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof Target)) return false; 

     Target target = (Target) o; 

     if (this.target != target.target) return false; 
     if (targetId != null ? !targetId.equals(target.targetId) : target.targetId != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = targetId != null ? targetId.hashCode() : 0; 
     result = 31 * result + target; 
     return result; 
    } 
} 

직원 엔티티 타겟에 포함

@Entity 
@Cacheable(true) 
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific 
public class Employee extends ProjectTeamMember { 
    ... 
    public Set<Language> getLanguages() { 
     return languages; 
    } 

    public void setLanguages(Set<Language> languages) { 
     this.languages = languages; 
    } 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "targetId.employeeId", cascade=CascadeType.ALL, orphanRemoval=true) 
    private Set<Target> targets = new HashSet<Target>(); 

    public Set<Target> getTargets() { 
     return targets; 
    } 

    public void setTargets(Set<Target> targets) { 
     this.targets = targets; 
    }  
    ... 
} 
관련 문제