Zapisywanie obiektu do bazy

0

Cześć
Mam klasę:

@Entity
@Table(name = "unit")
public class Unit implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "unit_id"unique = true)
    private int unitId;

    @Column(name = "name", nullable = false)
    private String name;
//...
}



@Entity
@Table(name = "ticket")
public class Ticket implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ticket_id")
    private int ticketId;

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "send_unit_id")
    private Unit senderUnit;

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "recieve_unit_id")
    private Unit recieverUnit;
//...
}

Chcę dodać nowy Ticket z istniejącymi Unit. Robię to tak:

            Unit senderUnit = sessionFactory.getCurrentSession().get(Unit.class, id);
            Unit recieverUnit = sessionFactory.getCurrentSession().get(Unit.class, id);

            Ticket ticket = new Ticket();
            ticket.setSenderUnit(senderUnit);
            ticket.setRecieverUnit(recieverUnit);
            
            sessionFactory.saveOrUpdate(ticket);

Problem w tym, ze dostaje wyjatek:
NonUniqueObjectException: a different object with the same identifier value was already associated with the session

Czytałem o tym tutaj http://pro-programmers.blogspot.com/2009/03/hibernate-nonuniqueobjectexception.html jednak to nic mi nie pomogło.
Otrzymuje ConstraintViolationException: could not execute statement

Mysle, ze cos zle robie w kodzie, ktory podeslalem powyzej.

0

A czy te klasy wyglądają dokładnie tak jak pokazałeś czy mają inne pola? Szczególnie: czy masz mapping w drugą stronę, OneToMany? Bo to byłby problem na moje oko. Wczytujesz sobie dwa obiekty Unit, ale to jest ten sam obiekt w bazie. Następnie robisz setSenderUnit co może powodować automatyczny merge bo sesja jest dalej aktywna w efekcie ten Unit dostaje wartość z swojego OneToMany, ale ten drugi obiekt który wyciągnęliśmy z bazy już nie. Następnie wykonujemy analogiczną operację dla drugiego obiektu i w efekcie mamy:

  • obiekt senderUnit z ustawionym ticketem jako sender
  • obiekt receiverUnit z ustawionym ticketem jako receiver
    więc te obiekty mają różny stan, ale mają to samo ID
    W efekcie przy zamykaniu sesji i transakcji hibernate znajdzie problem.
0

Te klasy wyglądają dokładnie tak (pomijam settery i gettery)

Unit: http://pastebin.com/szZEHYK2
Ticket: http://pastebin.com/YfimB50f

0

Dlaczego wykonujesz 2 razy "sessionFactory.getCurrentSession().get(Unit.class, id)" ?

Jeżeli senderUnit ma być tym samym, co recieverUnit, to zrób tak:

            Unit unit = sessionFactory.getCurrentSession().get(Unit.class, id);
 
            Ticket ticket = new Ticket();
            ticket.setSenderUnit(unit );
            ticket.setRecieverUnit(unit );
 
            sessionFactory.saveOrUpdate(ticket);

1 użytkowników online, w tym zalogowanych: 0, gości: 1