使用地图集合进行多对多休眠

时间:2010-01-20 00:24:39

标签: java hibernate nhibernate-mapping many-to-many

我有两张桌子“Station”和“Route”。路线可以包含许多站,每个站可以是不同路线的一部分。逻辑解决方案是创建一个包含'station_id'和'route_id'字段的表,互联网上有很多例子如何用hibernate组织所有这些东西。但是我需要在路线中存储每个站点的订单号,因此第3个表填充了另外一个字段'orderNumber',因此我们得到以下结构:

RouteStations

  • route_id
  • station_id
  • ORDERNUMBER

我创建了下一个bean:

public class Station extends Identifier{

    private String title;
}

public class Route extends Identifier{
    private String name;
    private Map<Integer, Station> stations = new HashMap<Integer, Station>();
}

所以我使用HashMap集合来存储orderNumber变量。 请帮助我使用hibernate映射这种类型的关系或提出其他解决方案。 感谢。

3 个答案:

答案 0 :(得分:1)

由于您必须在RouteStation表中存储额外信息,因此最好将其提升为完整类。你最终会得到这样的东西:

 public class Station extends Identifier{
    private String title;
    private List<RouteStation> routes;
 }

 public class Route extends Identifier{
    private String name;
    private List<RouteStation> stations;
 }

 Public class RouteStation{
     private Station station;
     private Route route;
     private Integer orderNumber;
 }

然后,您可以进行映射,以便RouteStation类拥有Route和Station之间的关系。您现在必须创建两个单独的一对多双向映射。

答案 1 :(得分:1)

Hummm,

  

我需要在路线中存储每个电台的订单号

为什么不使用List。您只需要创建一个链接表

@Entity
public class Route {

    private Integer id;

    private List<RouteAndStation> stationList = new ArrayList<RouteAndStation>();

    @Id
    public Integer getId() {
        return this.id;
    }

    @OneToMany(mappedBy="route")
    @Cascade(SAVE_UPDATE)
    public List<RouteAndStation> getStationList() {
        return this.stationList;
    }

    @Transient
    public List<Station> getStationByOrderNumber() {
        Collections.sort(this.stationList, new Comparator<RouteAndStation>() {
            public int compare(RouteAndStation o1, RouteAndStation o2) {
                return o1.getOrderNumber().compareTo(o2.getOrderNumber());
            }
        });

        List<Station> sList = new ArrayList();
        for(RouteAndStation routeAndStation: this.stationList)
            sList.add(routeAndStation.getStation());

        return sList;
    }

    public void addStation(Station station) {
        RouteAndStation routeAndStation = new RouteAndStation();

        routeAndStation.addStation(this, station, getStationList().size());

        getStationList().add(routeAndStation);
    }

}

和站

@Entity
public class Station {

    private Integer id;

    private List<RouteAndStation> routeList = new ArrayList<RouteAndStation>();

    @Id
    public Integer getId() {
       return this.id;
    }

    @OneToMany(mappedBy="station")
    // DO YOU NEDD CASCADE ???
    @Cascade(SAVE_UPDATE)
    public List<RouteAndStation> getRouteList() {
        return this.routeList;
    }


}

RouteAndStation实现如下

@Entity
public class RouteAndStation {

    private Route route;
    private Station station;

    private Integer stationNumber;

    private RouteAndStationId routeAndStationId;

    @EmbeddedId
    public RouteAndStationId getRouteAndStationId() {
        return this.routeAndStationId;
    }

    public void addStation(Route route, Station station, Integer stationNumber) {
        this.route = route;
        this.station = station;

        this.stationNumber = stationNumber;

        setRouteAndStationId(new RouteAndStationId(route.getId(), station.getId));
    }

    @ManyToOne(fetch=LAZY)
    @JoinColumn(name="ROUTE_ID", insertable=false, updateable=false)
    public Route getRoute() {
        return this.route;
    }

    @ManyToOne(fetch=LAZY)
    @JoinColumn(name="STATION_ID", insertable=false, updateable=false)
    public Station getStation() {
        return this.station;
    }

    @Embeddable
    public static class RouteAndStationId implements Serializable {

        private Integer routeId;
        private Integer stationId;

        // required no-arg constructor
        public RouteAndStationId() {}

        public RouteAndStationId(Integer routeId, Integer stationId) {
            this.routeId = routeId;
            this.stationId = stationId;
        }

        @Column(name="ROUTE_ID")
        public Integer getRouteId {
            return this.routeId;
        }

        @Column(name="STATION_ID")
        public Integer getStationId {
            return this.stationId;
        }

        public boolean equals(Object o) {
            if(o == null)
                return false;

            if(!(o instanceof RouteAndStationId))
                return false;

            RouteAndStationId other = (RouteAndStationId) o;
            if(!(getRouteId().equals(other.getRouteId())))
                return false;

            if(!(getStationId().equals(other.getStationId())))
                return false;

            return true;
        }

    }

}

我希望它对你有用

的问候,

答案 2 :(得分:0)

非常感谢。但我认为不应该有'RouteAndStation'实体。我试图在数据库中的两个表上映射我的'Route'类,如下所示:

<class name="Route" table="Route">

    <id name="id" column="routeId" type="long" unsaved-value="-1">
            <generator class="native"/>
    </id>

    <property name="name" column="name" />

    <map name="stations" table="RouteStations" cascade="all">
            <key column="routeId" />
            <map-key-many-to-many column="stationId" class="Station"/>
            <element column="orderNumber" type="int"/>
        </map>

</class>

但是当我保存Route对象时,只有一个查询由hibernate执行:

insert into Route (name) values (?)