JPA / Hibernate如何将业务字段添加到与连接表

时间:2016-02-26 14:39:40

标签: java hibernate jpa many-to-many

我使用带有额外列的连接表有多对多关系。这意味着在我的连接表中,我有一个由两个外键组成的复合主键。我也有一个业务专栏。 我想将业务列添加到主键,以便我能够在连接表中插入两个具有相同外键但在业务列中具有不同值的记录。可能吗 ? 我正在使用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;
    }
}

我有一个包含实际路由的文件,我想构建一个没有重复的路由引用。 两条路线相当于#34;如果它们具有相同顺序的相同段,并且每个段内的距离等于对另一个路径中相同段的距离的5%容差。在这种情况下,我不会插入任何新路线。否则,如果需要,我会插入一个包含新段的新路线,或者使用一些现有的段。

在某些情况下,我在路由中有相同的段但顺序不同,当我尝试在决定创建新的段之前从数据库中检索段时,这会导致Hibernate出现问题。

=====

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)

看来Hibernates在会话中创建了一个关联,当它试图在同一个段和第二次路由之间建立新的关联时,它会失败,因为该关联已经存在。

我想采取&#34;命令&#34;字段考虑在内,如果订单不相同,则允许路径和段之间的许多关联。如何处理这个

提前谢谢。

此致

0 个答案:

没有答案