org.hibernate.QueryException:@ManyToOne Criteria的重复关联路径

时间:2013-02-15 13:44:49

标签: java hibernate-mapping hibernate-criteria hibernate-annotations hibernate-4.x

我有两个类,它们之间有关系。这些是

com.edfx.adb.persist.Activity

package com.edfx.adb.persist.entity;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NaturalId;

@javax.persistence.Entity
@Table(name = "ACTIVITY")
public class Activity extends Entity {

    @Transient
    private static final long serialVersionUID = 4741665931936809028L;

    private String activityId;
    private String activityName;
    private String activityDescription;
    private Customer customer;
    private ActivityType activityType;
    private boolean active;
    private Double mandays;
    private Double price;
    private String manager;
    private List<Participation> participations;

    public Activity() {
        super();
    }

    @NaturalId
    @Column(name = "ACTIVITY_ID", nullable = false)
    public String getActivityId() {
        return activityId;
    }

    public void setActivityId(String activityId) {
        this.activityId = activityId;
    }

    @Lob
    @Column(name = "ACTIVITY_NAME", nullable = false)
    public String getActivityName() {
        return activityName;
    }

    public void setActivityName(String activityName) {
        this.activityName = activityName;
    }

    @Lob
    @Column(name = "ACTIVITY_DESCRIPTION", nullable = false)
    public String getActivityDescription() {
        return activityDescription;
    }

    public void setActivityDescription(String activityDescription) {
        this.activityDescription = activityDescription;
    }

    @ManyToOne
    @JoinColumn(name = "CUSTOMER_ID", nullable = false)
    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    @ManyToOne
    @JoinColumn(name = "ACTIVITY_TYPE_ID", nullable = false)
    public ActivityType getActivityType() {
        return activityType;
    }

    public void setActivityType(ActivityType activityType) {
        this.activityType = activityType;
    }

    @Column(name = "ACTIVE", nullable = false)
    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    @Column(name = "MANDAYS")
    public Double getMandays() {
        return mandays;
    }

    public void setMandays(Double mandays) {
        this.mandays = mandays;
    }

    @Column(name = "PRICE")
    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Column(name = "CUSTOMER_SIDE_MANAGER")
    public String getManager() {
        return manager;
    }

    public void setManager(String manager) {
        this.manager = manager;
    }

    @OneToMany(mappedBy = "activity", fetch = FetchType.LAZY)
    @Cascade(CascadeType.SAVE_UPDATE)
    public List<Participation> getParticipations() {
        return participations;
    }

    public void setParticipations(List<Participation> participations) {
        this.participations = participations;
    }
}

com.edfx.adb.persist.ActivityType

package com.edfx.adb.persist.entity;

import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;

@javax.persistence.Entity
@Table(name = "ACTIVITY_TYPE")
public class ActivityType extends Entity {

    @Transient
    private static final long serialVersionUID = 2322745769010162801L;

    private String parent;
    private String name;
    private String activityId;

    public ActivityType() {

    }

    @Column(name = "PARENT", nullable = false)
    public String getParent() {
        return parent;
    }

    public void setParent(String parent) {
        this.parent = parent;
    }

    @Column(name = "NAME", nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "ACTIVITY_ID", nullable = false)
    public String getActivityId() {
        return activityId;
    }

    public void setActivityId(String activityId) {
        this.activityId = activityId;
    }
}

它们都延伸com.edfx.adb.persist.entity.Entity

package com.edfx.adb.persist.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.hibernate.proxy.HibernateProxyHelper;

@MappedSuperclass
public class Entity implements Serializable {

    @Transient
    private static final long serialVersionUID = 7470288121057059283L;

    private Long id;
    private Date createTimestamp;
    private Date lastUpdateTimestamp;
    private Long version;

    public Entity() {
        super();
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", updatable = false, nullable = false, unique = true)
    public Long getId() {
        return id;
    }

    @SuppressWarnings("unused")
    private void setId(Long id) {
        this.id = id;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATE_TIMESTAMP")
    public Date getCreateTimestamp() {
        return createTimestamp;
    }

    public void setCreateTimestamp(Date createTimestamp) {
        this.createTimestamp = createTimestamp;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "LAST_UPDATE_TIMESTAMP")
    public Date getLastUpdateTimestamp() {
        return lastUpdateTimestamp;
    }

    public void setLastUpdateTimestamp(Date lastUpdateTimestamp) {
        this.lastUpdateTimestamp = lastUpdateTimestamp;
    }

    @Version
    @Column(name = "VERSION")
    public Long getVersion() {
        return version;
    }

    @SuppressWarnings("unused")
    private void setVersion(Long version) {
        this.version = version;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        return prime * result + ((getId() == null) ? super.hashCode() : getId().hashCode());
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (!getClass().equals(HibernateProxyHelper.getClassWithoutInitializingProxy(obj))) {
            return false;
        }

        final Entity other = (Entity) obj;

        if (getId() != other.getId()) {
            if (getId() == null) {
                return false;
            }
            if (!getId().equals(other.getId())) {
                return false;
            }
        }

        return true;
    }
}

现在我使用Primefaces数据表来显示List<Activity>,其中我已对name的字段ActivityType进行过滤。 ActivityTypeActivity关联@ManyToOne

过滤我正在使用的List<Activity>

Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);
criteria.createCriteria("activityType").add(Restrictions.like("name", value.toString(), MatchMode.START));

我得到了:

null: org.hibernate.QueryException: duplicate association path: activityType
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.createAssociationPathCriteriaMap(CriteriaQueryTranslator.java:172) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.<init>(CriteriaQueryTranslator.java:111) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
    at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:84) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1602) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
    at com.edfx.adb.dao.ActivityDao.loadActivities(ActivityDao.java:54) [classes:]
    at com.edfx.adb.service.ActivityService.loadActivities(ActivityService.java:101) [classes:]

此错误不会始终显示,也不会在第一次加载后显示。过滤表5-6次后,我遇到了这个错误。

我担心如果映射和标准是否正确。任何建议都会非常有用。

1 个答案:

答案 0 :(得分:6)

我认为您需要提供别名,因此您应该以这种方式更改代码:

Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);

criteria.createCriteria("activityType", "at")
   .add(
       Restrictions.like("at.name", value.toString(), MatchMode.START));