许多与许多关系与额外的列查询Hibernate

时间:2014-11-09 03:48:54

标签: java mysql hibernate

我在Hibernate中与一个额外的列成功建立了@ManyToMany关系,如下所示。

Activity.class

@Entity
@Table(name = "Activity")
public class Activity {

    @Id
    @GeneratedValue
    private int actId;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.activity", 
            cascade = { CascadeType.ALL, CascadeType.REMOVE })
    private Set<ActivityRepairMap> activityRepairMaps = new HashSet<ActivityRepairMap>();

    @NotEmpty
    private String actTurno;

    @NotEmpty
    private String actTexto;

    private String actFhc;    

    public Activity() {
    }    
    // Getters and Setters
}

Repair.class

@Entity
@Table(name = "Repair2")
public class Repair {

    @Id
    @GeneratedValue
    private int repId;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.repair")
    private Set<ActivityRepairMap> activityRepairMaps = new HashSet<ActivityRepairMap>();

    @NotEmpty(message=Constants.EMPTY_FIELD)
    private String repNombre;

    private Integer repCant;

    public Repair() {
    }    
    // Getters and Setters
}

ActivityRepairMap.class

@Entity
@Table(name="ActivityRepairMap")
@AssociationOverrides({
    @AssociationOverride(name="pk.activity", joinColumns=@JoinColumn(name="actId")),    
    @AssociationOverride(name="pk.repair", joinColumns=@JoinColumn(name="repId"))   
    })
public class ActivityRepairMap {

    private ActivityRepairId pk = new ActivityRepairId();
    private Integer actRepCant;

    @EmbeddedId
    public ActivityRepairId getPk() {
        return pk;
    }

    public void setPk(ActivityRepairId pk) {
        this.pk = pk;
    }

    @Transient
    public Activity getActivity() {
        return getPk().getActivity();
    }

    public void setActivity(Activity activity) {
        getPk().setActivity(activity);
    }

    @Transient
    public Repair getRepair() {
        return getPk().getRepair();
    }

    public void setRepair(Repair repair) {
        getPk().setRepair(repair);
    }

    @Column(name="actRepCant")
    public Integer getActRepCant() {
        return actRepCant;
    }

    public void setActRepCant(Integer actRepCant) {
        this.actRepCant = actRepCant;
    }

    public ActivityRepairMap (){

    }    
    // hashCode and equals methods
}

ActivityRepairId

@Embeddable
public class ActivityRepairId implements Serializable{

    private static final long serialVersionUID = -776429030880521951L;
    private Activity activity;
    private Repair repair;

    @ManyToOne
    public Activity getActivity() {
        return activity;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    @ManyToOne
    public Repair getRepair() {
        return repair;
    }

    public void setRepair(Repair repair) {
        this.repair = repair;
    }    
    // hashCode and equals method
}

我的问题是我无法查询特定活动中使用的所有修复。 我已经在MySQL Workbench中检查过存储在DB中的数据是否正确。 如果有人能用HQL或Criteria解释我怎么能实现这个目标,我将不胜感激。

非常感谢。

1 个答案:

答案 0 :(得分:0)

在SQL中,这应该是:

SELECT
  r.*
FROM 
  repair r
LEFT JOIN
  activity_repair ar 
    ON
      ar.repair_id = r.id
WHERE
  ar.activity_id = ?

现在,单个activity仍然可能与两个repair连接,尽管您可能会在结果列表中进行两次修复。您可以简单地使用SELECT DISTINCT r.*解决此问题,或使用子查询。

在JPQL中,查询应该与上面的SQL基本相同。

SELECT
  r
FROM 
  Repair r
WHERE
  r.activityRepairMaps.pk.activity = ?

如果您需要加入:

SELECT
  r
FROM 
  Repair r
JOIN
  ActivityRepairMap arm
WHERE
  arm.pk.activity = ?

也许您需要在ActivityRepairMaps类中使用@MapsId。 (我现在还没有完成JPQL一段时间)

据我记得,您不应在@EmbeddedId类中使用实体,而应使用相应类的原始@Id类型。您应该使用RepairActivity而不是intint