Hibernate многие-ко-многим с коллекцией карт - PullRequest
2 голосов
/ 20 января 2010

У меня есть две таблицы «Станция» и «Маршрут». Маршрут может содержать много станций, и каждая станция может быть частью различных маршрутов. Логическим решением является создание таблицы с полями «station_id» и «route_id», и в Интернете есть много примеров, как организовать все эти вещи с помощью hibernate. Но мне нужно сохранить порядковый номер каждой станции в маршруте, поэтому 3-я таблица заполняется еще одним полем 'orderNumber', поэтому мы получаем следующую структуру:

RouteStations

  • route_id
  • station_id
  • ORDERNUMBER

Я создал следующие бины:

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 ]

1 голос
/ 20 января 2010

Хм,

Мне нужно хранить номер заказа каждой станции на маршруте

Почему вы не используете Списоквместо.Вам просто нужно создать связанную таблицу

@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);
    }

}

И Station

@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;
        }

    }

}

Надеюсь, это может быть полезно для вас

С уважением,

1 голос
/ 20 января 2010

Так как вам нужно хранить дополнительную информацию в таблице 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 владел отношениями между маршрутом и станцией. Теперь вам нужно создать два отдельных двунаправленных отображения «один ко многим».

0 голосов
/ 20 января 2010

Спасибо большое. Но я думаю, что не должно быть сущности RouteAndStation. Я попытался сопоставить свой класс «Маршрут» с двумя таблицами в базе данных следующим образом:

<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 (?)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...