Java JPA/Hibernate如何将业务字段添加到连接表的多对多关联的主键中

Java JPA/Hibernate如何将业务字段添加到连接表的多对多关联的主键中,java,hibernate,jpa,many-to-many,Java,Hibernate,Jpa,Many To Many,我使用一个带有额外列的联接表来建立多对多关系。这意味着在我的联接表中有一个由两个外键组成的复合主键。我还有一个商业专栏。 我希望将业务列添加到主键中,以便能够在联接表中插入两条记录,它们具有相同的外键,但在业务列中具有不同的值。可能吗? 我正在使用JPA和Hibernate对我的数据库进行建模 下面是更多的代码细节 @Entity @Table(name = "ROUTE") @SequenceGenerator(name = "SEQ_ROUTE", sequenceN

我使用一个带有额外列的联接表来建立多对多关系。这意味着在我的联接表中有一个由两个外键组成的复合主键。我还有一个商业专栏。 我希望将业务列添加到主键中,以便能够在联接表中插入两条记录,它们具有相同的外键,但在业务列中具有不同的值。可能吗? 我正在使用JPA和Hibernate对我的数据库进行建模 下面是更多的代码细节

    @Entity
    @Table(name = "ROUTE")
    @SequenceGenerator(name = "SEQ_ROUTE", sequenceName = "SEQ_ROUTE", allocationSize = 1)

    public class Route implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long id;
        private String name;
        private String origin;
        private String destination;
        private Date updateTimestamp;


        private Set<RouteSegmentAssociation> routeSegmentAssociations = new HashSet<RouteSegmentAssociation>(
                0);

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.route", cascade = CascadeType.ALL)
        public Set<RouteSegmentAssociation> getRouteSegmentAssociations() {
            return routeSegmentAssociations;
        }

        public void setRouteSegmentAssociations(
                Set<RouteSegmentAssociation> routeSegmentAssociations) {
            this.routeSegmentAssociations = routeSegmentAssociations;
        }

        private List<Route> actualRoutes;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "referenceRoute", cascade = CascadeType.ALL)
        public List<ActualRoute> getActualRoutes() {
            return actualRoutes;
        }

        public void setActualRoutes(List<ActualRoute> actualRoutes) {
            this.actualRoutes = actualRoutes;
        }

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ROUTE")
        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        ////
        }

    @Entity
    @Table(name = "SEGMENT")
    @SequenceGenerator(name = "SEQ_SEGMENT", sequenceName = "SEQ_SEGMENT", allocationSize = 1)
    public class Segment implements Serializable {

        private static final long serialVersionUID = 1L;

        private Long id;

        private String name;
        private String entry;
        private String exit;
        private int distance;
        private Date updateTimestamp;

        private Set<RouteSegmentAssociation> routeSegmentAssociations = new HashSet<RouteSegmentAssociation>(
                0);

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.segment", cascade = CascadeType.ALL)
        public Set<RouteSegmentAssociation> getRouteSegmentAssociations() {
            return routeSegmentAssociations;
        }

        public void setRouteSegmentAssociations(
                Set<RouteSegmentAssociation> routeSegmentAssociations) {
            this.routeSegmentAssociations = routeSegmentAssociations;
        }

        //getters and setters


    }

@Entity
@Table(name = "ROUTE_SEGMENT_CROSS")
@AssociationOverrides({
        @AssociationOverride(name = "pk.route", joinColumns = @JoinColumn(name = "ID_ROUTE")),
        @AssociationOverride(name = "pk.segment", joinColumns = @JoinColumn(name = "ID_SEGMENT")) })
public class RouteSegmentAssociation implements Serializable {

    private static final long serialVersionUID = 1L;

    private RouteSegmentID pk = new RouteSegmentID();

    private int order;

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

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

    @Transient
    public Route getRoute() {
        return getPk().getRoute();
    }

    public void setRoute(Route route) {
        getPk().setRoute(route);
    }

    @Transient
    public Segment getSegment() {
        return getPk().getSegment();
    }

    public void setSegment(Segment segment) {
        getPk().setSegment(segment);
    }

    @Column(name="ORDER")
    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int hashCode() {
        return (getPk() != null ? getPk().hashCode() : 0);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof RouteSegmentAssociation))
            return false;
        RouteSegmentAssociation other = (RouteSegmentAssociation) obj;
        if (pk == null) {
            if (other.pk != null)
                return false;
        } else if (!pk.equals(other.pk))
            return false;
        if (order != other.order)
            return false;
        return true;
    }
}
Hibernates似乎在会话中创建了一个关联,当它第二次尝试在同一段和路由之间创建一个新关联时,它失败了,因为该关联已经存在

我想考虑“顺序”字段,如果顺序不同,则允许在路线和线段之间建立许多关联。如何应对

先谢谢你


关于

如果我理解正确,您需要将“订单”移动到RouteSegmentID。为什么不将
订单
添加到组合PK中?是的,我想将订单添加到组合键,但我不知道如何操作?我想允许重复对(routeID,segmentID),除非“订单”相同。
at xxx.xxx.xxx.save(RouteDS.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy30.save(Unknown Source)
at xxx.xxx.xxx.batch.RouteStats.inserteRoute(RouteStats.java:586)
**Caused by: javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [xxx.xxx.xxx.RouteSegmentAssociation#RouteSegmentID [route=88457, segment=101943]]**
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1359)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:255)
at xxx.xxx.xxxx.SegmentDAO.findByDescriminants(SegmentDAO.java:88)