Spring Data - Hibernate many-to-many mentés

Spring Data - Hibernate many-to-many mentés
2015-12-03T13:21:32+01:00
2015-12-03T22:28:25+01:00
2022-10-15T23:16:05+02:00
vargai
Sziasztok!
Két adatbázis táblám között many-to-many kapcsolat van. A Spring Data létrehozza az adatbázis táblákat megfelelően, viszont ha elmentek egy event-et nem adja hozzá a user_event táblához, hogy melyik user hozta létre az event-et.

A User osztályban létrehoztam a many-to-many kapcsolatot:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "user_event", joinColumns = { @JoinColumn(name = "user_id")}, inverseJoinColumns = {@JoinColumn(name = "event_id", nullable = false, updatable = false)}) private Set<Event> events = new HashSet<Event>(0);
+setter, getter...

Az event osztály:

@Entity @Table(name = "events") public class Event { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "event_name") private String eventName; @Column(name = "event_description") private String eventDescription; @Column(name = "creation_date", updatable = false) private Date creationDate; @Column(name = "event_date") private Date eventDate; @Column(name = "flag") private byte flag; @Column(name = "user_id") private long userId; //@JsonProperty("userId") @ManyToMany(fetch = FetchType.LAZY, mappedBy = "events") private Set<User> users = new HashSet<User>(0); @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "event_category", joinColumns = { @JoinColumn(name = "event_id", nullable = false, updatable = false)}, inverseJoinColumns = {@JoinColumn(name = "category_id", nullable = false)}) private Set<Category> categories = new HashSet<Category>(0);
EventService:

public void saveEvent(Event event){ try { event.setCreationDate(new Date()); User user = new User(event.getUserId()); event.getUsers().add(user); eventDao.save(event); }catch (Exception e){ e.printStackTrace(); } }
És a Controller:

@RequestMapping(value = "/addevent", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public String createEvent(@RequestBody Event event) { try { eventService.saveEvent(event); } catch (Exception ex) { return "Error creating the event:" + ex.toString(); } return "Event succesfully created!"; }
REST kliensben ezt küldöm:

{ "userId":1, "account": 1, "eventName":"resttest", "eventDescription":"restTest" , "eventDate":"2012-04-23T18:25:43.511Z" }
Mutasd a teljes hozzászólást!
Amit fontos észben tartani, hogy a JPA/Hibernate ManyToMany kapcsolatánál az egyik oldal a tulajdonos (owner side), a másik pedig az inverz (inverse side). A tulajdonos az az oldal, amelyiknek nincs mappedBy attribútuma. A te feladatod a két oldalt szinkronizálni, viszont mentésnél a Hibernate mindenképp a tulajdonos oldalt fogja figyelembe venni (akkor is, ha az inverz oldalt nem frissítetted). Te a fenti kódban pont csak az inverz oldalt frissíted. Tehát helyesen vagy megcseréled a két oldalt, vagy a User-en keresztül frissíted a kapcsolatot.

Egyébként szerintem OneToMany lenne a helyes kapcsolat: egy user generálhat több eventet, míg egy eventet egy user generál

User (1) - - - (*) Event
Mutasd a teljes hozzászólást!

  • Ha ManyToMany, akkor szerintem a másik oldalról is be kell állítani a kapcsolatot, tehát a User entitásnak is kell legyen kapcsolata az Event entitással és a user.getEvents().add(event) hiányzik.

    Az egy másik kérdés, hogy tényleg szükség van-e a ManyToMany-re ebben az esetben,  bár nem látom át a konkrét helyzetet. Szerintem elég lenne egy OneToOne, tehát egy event-et egy user generál.
    Mutasd a teljes hozzászólást!
  • Úgy képzeltem el, hogy egy user több event-et hozhat létre és egy event-hez több user is csatlakozhat. Akkor kell user.getEvents().add(event) és event.getUsers().add(user) is?
    Mutasd a teljes hozzászólást!
  • Amit fontos észben tartani, hogy a JPA/Hibernate ManyToMany kapcsolatánál az egyik oldal a tulajdonos (owner side), a másik pedig az inverz (inverse side). A tulajdonos az az oldal, amelyiknek nincs mappedBy attribútuma. A te feladatod a két oldalt szinkronizálni, viszont mentésnél a Hibernate mindenképp a tulajdonos oldalt fogja figyelembe venni (akkor is, ha az inverz oldalt nem frissítetted). Te a fenti kódban pont csak az inverz oldalt frissíted. Tehát helyesen vagy megcseréled a két oldalt, vagy a User-en keresztül frissíted a kapcsolatot.

    Egyébként szerintem OneToMany lenne a helyes kapcsolat: egy user generálhat több eventet, míg egy eventet egy user generál

    User (1) - - - (*) Event
    Mutasd a teljes hozzászólást!
  • Köszönöm! Megcseréltem és most működik. Azért akarok ManyToMany kapcsolatot, hogy egy eseményhez majd több felhasználó is csatlakozhat. Lehet, hogy nem jól gondolom.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd