Сохранение отношения OneToMany сохраняет только первый объект в наборе? - PullRequest
2 голосов
/ 01 сентября 2010

Возился с Hibernate и PostgreSQL, пытаясь заставить его работать как положено.

Но по какой-то причине, когда я пытаюсь сохранить объект с отношениями @ OneToMany с более чемодин элемент в наборе все, кроме первого, кажется, игнорируются.Я пробовал это через локальный и удаленный интерфейсы, но каждый раз получал одинаковые результаты.Никаких исключений не выдается, похоже, что hibernate просто перестает существовать после сохранения первого модуля.

Любая помощь, которая высоко ценится, ускользает от меня уже несколько дней.

Я используюHibernate 3.5 и PostgreSQL 8.4.4 с Glassfish v3.Все аннотации в источнике взяты из пакета javax.persistence - пришлось удалить импорт из-за ограничения по количеству символов.

FacadeManager - это просто утилита, облегчающая поиск jndi, она упрощает доступ к удаленным фасадам.

Вот метод испытания

    @Test
    public void testOneToManyCascade() throws Exception {
        /*
         * Set up entities requred to perform the test
         */
        UnitFacadeRemote unitfr = FacadeManager
                .getFacade(UnitFacadeRemote.class);
        UserFacadeRemote userfr = FacadeManager
                .getFacade(UserFacadeRemote.class);

        User user = new User("P", "P", "000000", true, new Date(), "ypy@ypy",
                "wordof mout", "slacker", "password");

        Address address = new Address("yo", "go", "YOKO", "4123");
        address.setCountry(FacadeManager.getFacade(CountryFacadeRemote.class)
                .find(2));
        user.setAddress(address);

        Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService",
                "MyNation");
        Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService",
                "TheirNation");
        Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService",
                "TheirNation");

        // Check no game exists
        assertThat(FacadeManager.getFacade(GameFacadeRemote.class).findAll()
                .size(), is(0));

        Game game = new Game("blabla", 3333, "A game!", true);

        // Create game and return reference to persisted game instance
        game = FacadeManager.getFacade(GameFacadeRemote.class).registerGame(
                game);

        unit1.setGame(game);
        unit2.setGame(game);
        unit3.setGame(game);

        // Find a virtue
        Virtue v = FacadeManager.getFacade(VirtueFacadeRemote.class).find(1);

        unit1.setVirtue(v);
        unit2.setVirtue(v);
        unit3.setVirtue(v);

        // check that none of the above exist already
        assertThat(userfr.findAll().size(), is(0));
        assertThat(unitfr.findAll().size(), is(0));

        /*
         * Try persisting the by cascading from the user
         */

        Set<Unit> unitSet = new HashSet<Unit>();
        unitSet.add(unit2);
        unitSet.add(unit1);
        unitSet.add(unit3);
        user.setUnitSet(unitSet);
        unit1.setUser(user);
        unit2.setUser(user);
        unit3.setUser(user);

        // Persist
        userfr.create(user);

        /*
         * The result of the preceding persist is that the game, user, address
         * and one unit are persisted, in this case unit2 but it seems whichever
         * unit is first added to unitSet is the one that is persisted.
         */
    }

Here follow the various entity classes
package com.game.database.entity;

@Entity
@Table(name = "address")
@NamedQueries({
        @NamedQuery(name = "Address.findAll", query = "SELECT a FROM Address a"),
        @NamedQuery(name = "Address.findById", query = "SELECT a FROM Address a WHERE a.id = :id"),
        @NamedQuery(name = "Address.findByLine1", query = "SELECT a FROM Address a WHERE a.line1 = :line1"),
        @NamedQuery(name = "Address.findByLine2", query = "SELECT a FROM Address a WHERE a.line2 = :line2"),
        @NamedQuery(name = "Address.findByCity", query = "SELECT a FROM Address a WHERE a.city = :city"),
        @NamedQuery(name = "Address.findByAreaCode", query = "SELECT a FROM Address a WHERE a.areaCode = :areaCode") })
public class Address implements Serializable {
    private static final long serialVersionUID = 1L;
    @SequenceGenerator(name = "address_id_seq", sequenceName = "address_id_seq", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "address_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "line1")
    private String line1;
    @Basic(optional = false)
    @Column(name = "line2")
    private String line2;
    @Basic(optional = false)
    @Column(name = "city")
    private String city;
    @Basic(optional = false)
    @Column(name = "areaCode")
    private String areaCode;
    @JoinColumn(name = "country", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Country country;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
    private Set<User> userSet;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
    private Set<CardDetails> cardDetailsSet;

    public Address() {
    }

    public Address(Integer id) {
        this.id = id;
    }

    public Address(String line1, String line2, String city, String areaCode) {
        this.line1 = line1;
        this.line2 = line2;
        this.city = city;
        this.areaCode = areaCode;
    }

    public Integer getId() {
        return id;
    }

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

    public String getLine1() {
        return line1;
    }

    public void setLine1(String line1) {
        this.line1 = line1;
    }

    public String getLine2() {
        return line2;
    }

    public void setLine2(String line2) {
        this.line2 = line2;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getAreaCode() {
        return areaCode;
    }

    public void setAreaCode(String areaCode) {
        this.areaCode = areaCode;
    }

    public Country getCountry() {
        return country;
    }

    public void setCountry(Country country) {
        this.country = country;
    }

    public Set<User> getUserSet() {
        return userSet;
    }

    public void setUserSet(Set<User> userSet) {
        this.userSet = userSet;
    }

    public Set<CardDetails> getCardDetailsSet() {
        return cardDetailsSet;
    }

    public void setCardDetailsSet(Set<CardDetails> cardDetailsSet) {
        this.cardDetailsSet = cardDetailsSet;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof Address)) {
            return false;
        }
        Address other = (Address) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.Address[id=" + id + "]";
    }
}

-

package com.game.database.entity;

@Entity
@Table(name = "game")
@NamedQueries({
        @NamedQuery(name = "Game.findAll", query = "SELECT g FROM Game g"),
        @NamedQuery(name = "Game.findById", query = "SELECT g FROM Game g WHERE g.id = :id"),
        @NamedQuery(name = "Game.findByHost", query = "SELECT g FROM Game g WHERE g.host = :host"),
        @NamedQuery(name = "Game.findByPort", query = "SELECT g FROM Game g WHERE g.port = :port"),
        @NamedQuery(name = "Game.findByDescription", query = "SELECT g FROM Game g WHERE g.description = :description"),
        @NamedQuery(name = "Game.findByActive", query = "SELECT g FROM Game g WHERE g.active = :active"),
        @NamedQuery(name = "Game.findByHostAndPort", query = "SELECT g FROM Game g WHERE g.host = :host AND g.port = :port") })
public class Game implements Serializable {
    private static final long serialVersionUID = 1L;
    @SequenceGenerator(name = "game_id_seq", sequenceName = "game_id_seq", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "game_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "host")
    private String host;
    @Basic(optional = false)
    @Column(name = "port")
    private int port;
    @Basic(optional = false)
    @Column(name = "description")
    private String description;
    @Basic(optional = false)
    @Column(name = "active")
    private Boolean active;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
    private Set<Unit> unitSet;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
    private Set<Payment> paymentSet;

    public Game() {
    }

    public Game(Integer id) {
        this.id = id;
    }

    public Game(String host, int port, String description, Boolean active) {
        this.host = host;
        this.port = port;
        this.description = description;
        this.active = active;
    }

    public Integer getId() {
        return id;
    }

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

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Boolean getActive() {
        return active;
    }

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

    public Set<Unit> getUnitSet() {
        return unitSet;
    }

    public void setUnitSet(Set<Unit> unitSet) {
        this.unitSet = unitSet;
    }

    public Set<Payment> getPaymentSet() {
        return paymentSet;
    }

    public void setPaymentSet(Set<Payment> paymentSet) {
        this.paymentSet = paymentSet;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof Game)) {
            return false;
        }
        Game other = (Game) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.Game[id=" + id + "]";
    }
}

-

package com.game.database.entity;

@Entity
@Table(name = "unit")
@NamedQueries({
        @NamedQuery(name = "Unit.findAll", query = "SELECT u FROM Unit u"),
        @NamedQuery(name = "Unit.findById", query = "SELECT u FROM Unit u WHERE u.id = :id"),
        @NamedQuery(name = "Unit.findByUnitId", query = "SELECT u FROM Unit u WHERE u.unitId = :unitId"),
        @NamedQuery(name = "Unit.findByName", query = "SELECT u FROM Unit u WHERE u.name = :name"),
        @NamedQuery(name = "Unit.findByRegistrationDate", query = "SELECT u FROM Unit u WHERE u.registrationDate = :registrationDate"),
        @NamedQuery(name = "Unit.findByService", query = "SELECT u FROM Unit u WHERE u.service = :service"),
        @NamedQuery(name = "Unit.findByNation", query = "SELECT u FROM Unit u WHERE u.nation = :nation") })
public class Unit implements Serializable {
    private static final long serialVersionUID = 1L;
    @SequenceGenerator(name = "unit_id_seq", sequenceName = "unit_id_seq", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "unit_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "unitId")
    private Integer unitId;
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @Column(name = "registrationDate")
    @Temporal(TemporalType.TIMESTAMP)
    private Date registrationDate;
    @Basic(optional = false)
    @Column(name = "service")
    private String service;
    @Basic(optional = false)
    @Column(name = "nation")
    private String nation;
    @JoinColumn(name = "virtue", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Virtue virtue;
    @JoinColumn(name = "customer", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private User customer;
    @JoinColumn(name = "game", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Game game;

    public Unit() {
    }

    public Unit(Integer id) {
        this.id = id;
    }

    public Unit(Integer unitId, String name, Date registrationDate,
            String service, String nation) {
        this.unitId = unitId;
        this.name = name;
        this.registrationDate = registrationDate;
        this.service = service;
        this.nation = nation;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getUnitId() {
        return unitId;
    }

    public void setUnitId(Integer unitId) {
        this.unitId = unitId;
    }

    public String getName() {
        return name;
    }

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

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    public String getService() {
        return service;
    }

    public void setService(String service) {
        this.service = service;
    }

    public String getNation() {
        return nation;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    public Virtue getVirtue() {
        return virtue;
    }

    public void setVirtue(Virtue virtue) {
        this.virtue = virtue;
    }

    public User getUser() {
        return customer;
    }

    public void setUser(User user) {
        this.customer = user;
    }

    public Game getGame() {
        return game;
    }

    public void setGame(Game game) {
        Logger.getLogger("org.hibernate").setLevel(Level.FINEST);
        this.game = game;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof Unit)) {
            return false;
        }
        Unit other = (Unit) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.Unit[id=" + id + "]";
    }

    @Transient
    private String command;

    /**
     * Get the value of command
     * 
     * @return the value of command
     */
    public String getCommand() {
        return command;
    }

    /**
     * Set the value of command
     * 
     * @param command
     *            new value of command
     */
    public void setCommand(String command) {
        this.command = command;
    }

    @Transient
    private String rank;

    /**
     * Get the value of rank
     * 
     * @return the value of rank
     */
    public String getRank() {
        return rank;
    }

    /**
     * Set the value of rank
     * 
     * @param rank
     *            new value of rank
     */
    public void setRank(String rank) {
        this.rank = rank;
    }

    @Transient
    private BigDecimal price;

    /**
     * Get the value of price
     * 
     * @return the value of price
     */
    public BigDecimal getPrice() {
        return price;
    }

    /**
     * Set the value of price
     * 
     * @param price
     *            new value of price
     */
    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

-

package com.game.database.entity;

@Entity
@Table(name = "customer")
@NamedQueries({
        @NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
        @NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
        @NamedQuery(name = "User.findByGivenName", query = "SELECT u FROM User u WHERE u.givenName = :givenName"),
        @NamedQuery(name = "User.findBySurname", query = "SELECT u FROM User u WHERE u.surname = :surname"),
        @NamedQuery(name = "User.findByPhoneNumber", query = "SELECT u FROM User u WHERE u.phoneNumber = :phoneNumber"),
        @NamedQuery(name = "User.findBySex", query = "SELECT u FROM User u WHERE u.sex = :sex"),
        @NamedQuery(name = "User.findByBirthYear", query = "SELECT u FROM User u WHERE u.birthYear = :birthYear"),
        @NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email"),
        @NamedQuery(name = "User.findByInfoSource", query = "SELECT u FROM User u WHERE u.infoSource = :infoSource"),
        @NamedQuery(name = "User.findByOccupation", query = "SELECT u FROM User u WHERE u.occupation = :occupation"),
        @NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password"),
        @NamedQuery(name = "User.findByEmailAndPassword", query = "SELECT u FROM User u WHERE u.password = :password AND u.email = :email") })
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "givenName")
    private String givenName;
    @Basic(optional = false)
    @Column(name = "surname")
    private String surname;
    @Basic(optional = false)
    @Column(name = "phoneNumber")
    private String phoneNumber;
    @Basic(optional = false)
    @Column(name = "sex")
    private boolean sex;
    @Basic(optional = false)
    @Column(name = "birthYear")
    @Temporal(TemporalType.DATE)
    private Date birthYear;
    @Basic(optional = false)
    @Column(name = "email")
    private String email;
    @Basic(optional = false)
    @Column(name = "infoSource")
    private String infoSource;
    @Basic(optional = false)
    @Column(name = "occupation")
    private String occupation;
    @Basic(optional = false)
    @Column(name = "password")
    private String password;
    /**
     * The EAGER fetch type ensures that when we get access a unit remotely it
     * has had its unit set initialised and populated
     */
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
    private Set<Unit> unitSet;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
    private Set<Payment> paymentSet;
    @JoinColumn(name = "address", referencedColumnName = "id")
    @ManyToOne(cascade = CascadeType.ALL, optional = false)
    private Address address;

    public User() {
    }

    public User(Integer id) {
        this.id = id;
    }

    public User(String givenName, String surname, String phoneNumber,
            boolean sex, Date birthYear, String email, String infoSource,
            String occupation, String password) {
        this.givenName = givenName;
        this.surname = surname;
        this.phoneNumber = phoneNumber;
        this.sex = sex;
        this.birthYear = birthYear;
        this.email = email;
        this.infoSource = infoSource;
        this.occupation = occupation;
        this.password = password;
    }

    public Integer getId() {
        return id;
    }

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

    public String getGivenName() {
        return givenName;
    }

    public void setGivenName(String givenName) {
        this.givenName = givenName;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public boolean getSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }

    public Date getBirthYear() {
        return birthYear;
    }

    public void setBirthYear(Date birthYear) {
        this.birthYear = birthYear;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getInfoSource() {
        return infoSource;
    }

    public void setInfoSource(String infoSource) {
        this.infoSource = infoSource;
    }

    public String getOccupation() {
        return occupation;
    }

    public void setOccupation(String occupation) {
        this.occupation = occupation;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Set<Unit> getUnitSet() {
        return unitSet;
    }

    public void setUnitSet(Set<Unit> unitSet) {
        this.unitSet = unitSet;
    }

    public Set<Payment> getPaymentSet() {
        return paymentSet;
    }

    public void setPaymentSet(Set<Payment> paymentSet) {
        this.paymentSet = paymentSet;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof User)) {
            return false;
        }
        User other = (User) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.User[id=" + id + "]";
    }
}

-

package com.game.database.entity;

@Entity
@Table(name = "virtue")
@NamedQueries({
        @NamedQuery(name = "Virtue.findAll", query = "SELECT v FROM Virtue v"),
        @NamedQuery(name = "Virtue.findById", query = "SELECT v FROM Virtue v WHERE v.id = :id"),
        @NamedQuery(name = "Virtue.findByName", query = "SELECT v FROM Virtue v WHERE v.name = :name"),
        @NamedQuery(name = "Virtue.findByDescription", query = "SELECT v FROM Virtue v WHERE v.description = :description") })
public class Virtue implements Serializable {
    private static final long serialVersionUID = 1L;
    @SequenceGenerator(name = "virtue_id_seq", sequenceName = "virtue_id_seq", allocationSize = 1)
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "virtue_id_seq")
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @Column(name = "description")
    private String description;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "virtue")
    private Set<Unit> unitSet;

    public Virtue() {
    }

    public Virtue(Integer id) {
        this.id = id;
    }

    public Virtue(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Unit> getUnitSet() {
        return unitSet;
    }

    public void setUnitSet(Set<Unit> unitSet) {
        this.unitSet = unitSet;
    }

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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof Virtue)) {
            return false;
        }
        Virtue other = (Virtue) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.Virtue[id=" + id + "]";
    }
}

Ответы [ 2 ]

3 голосов
/ 01 сентября 2010

У вас проблема с идентификацией объектов Юнитов.Вы используете в своем коде HashSet, который использует методы equals и hashCode, которые переопределяются в вашем коде.

Если вы запустите метод main в приведенном ниже коде, вы увидите, что после добавления объектов Unitтолько один из них в наборе (я повторно использовал ваш исходный код, но немного его упростил):

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public class Unit {

    private Integer id;

    private Integer unitId;
    private String name;
    private Date registrationDate;

    private String service;

    private String nation;

    public Unit() {
    }

    public Unit(Integer id) {
        this.id = id;
    }

    public Unit(Integer unitId, String name, Date registrationDate, String service, String nation) {
        this.unitId = unitId;
        this.name = name;
        this.registrationDate = registrationDate;
        this.service = service;
        this.nation = nation;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getUnitId() {
        return unitId;
    }

    public void setUnitId(Integer unitId) {
        this.unitId = unitId;
    }

    public String getName() {
        return name;
    }

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

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    public String getService() {
        return service;
    }

    public void setService(String service) {
        this.service = service;
    }

    public String getNation() {
        return nation;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }


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

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Unit)) {
            return false;
        }
        Unit other = (Unit) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.game.database.entity.Unit[id=" + id + "]";
    }


    public static void main(String... args) {

        Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService", "MyNation");
        Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService", "TheirNation");
        Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService", "TheirNation");

        Set unitSet = new HashSet();
        unitSet.add(unit2);
        unitSet.add(unit1);
        unitSet.add(unit3);

        System.out.println(unitSet.size());

    }

Если вы закомментируете equals () и hashCode () и снова запустите код, высм. три объекта в наборе.

Ваш метод equals () основан на свойстве id, которое устанавливается hibernate во время сохранения объекта, а не во время добавления в набор.Это означает, что модуль всегда имеет нулевой идентификатор и hashCode = 0 при добавлении в набор.Я рекомендую прочитать эту статью: http://community.jboss.org/wiki/EqualsandHashCode

Надеюсь, это поможет!

0 голосов
/ 01 сентября 2010

Вот хвост журналов Glassfish в случае, если это помогает - не может вписаться в исходное сообщение.

FINE:     insert 
    into
        address
        (areaCode, city, country, line1, line2, id) 
    values
        (?, ?, ?, ?, ?, ?)
INFO: Hibernate: 
    insert 
    into
        address
        (areaCode, city, country, line1, line2, id) 
    values
        (?, ?, ?, ?, ?, ?)
FINEST: preparing statement
FINEST: Dehydrating entity: [com.historicalengineering.wwii.database.entity.Address#156]
FINEST: id unsaved-value: null
FINEST: Inserting entity: [com.historicalengineering.wwii.database.entity.User#108]
FINE: Executing batch size: 1
FINE: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
FINEST: closing statement
FINE: skipping aggressive-release due to flush cycle
FINE: about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
FINE:     insert 
    into
        customer
        (address, birthYear, email, givenName, infoSource, occupation, password, phoneNumber, sex, surname, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
INFO: Hibernate: 
    insert 
    into
        customer
        (address, birthYear, email, givenName, infoSource, occupation, password, phoneNumber, sex, surname, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
FINEST: preparing statement
FINEST: Dehydrating entity: [com.historicalengineering.wwii.database.entity.User#108]
FINEST: Inserting entity: [com.historicalengineering.wwii.database.entity.Unit#147]
FINE: Executing batch size: 1
FINE: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
FINEST: closing statement
FINE: skipping aggressive-release due to flush cycle
FINE: about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
FINE:     insert 
    into
        unit
        (customer, game, name, nation, registrationDate, service, unitId, virtue, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?)
INFO: Hibernate: 
    insert 
    into
        unit
        (customer, game, name, nation, registrationDate, service, unitId, virtue, id) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?)
FINEST: preparing statement
FINEST: Dehydrating entity: [com.historicalengineering.wwii.database.entity.Unit#147]
FINEST: id unsaved-value: null
FINEST: id unsaved-value: null
FINE: Executing batch size: 1
FINE: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
FINEST: closing statement
FINE: skipping aggressive-release due to flush cycle
FINEST: registering flush end
FINE: aggressively releasing JDBC connection
FINE: releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
FINEST: post flush
FINEST: transaction after completion callback, status: 3
FINEST: after transaction completion
FINEST: after transaction completion
FINEST: TransactionFactory reported no active transaction; Synchronization not registered
FINEST: TransactionFactory reported no active transaction; Synchronization not registered
FINEST: TransactionFactory reported no active transaction; Synchronization not registered
FINEST: closing session
FINEST: connection already null in cleanup : no action
...