I have been trying to load the menu from a database using Spring JPA and Spring Boot with a MySQL database.
I have to load only active menu from database. I have tried with JPQL, i.e. findByActiveTrue() method of JPA, but I get all records.
#Entity
#Table(name = "menu_tbl")
//#Cacheable
//#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Menu implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "menu_description")
private String menuName;
#Column(name = "menu_link", nullable = false)
private String link;
#Column(name = "menu_css")
private String css;
#Column(name = "menu_ico")
private String icon;
#Column(name = "active")
#
private Boolean active;
#JsonManagedReference
#OneToMany(mappedBy = "parent")
#OrderBy("id ASC")
private Set<Menu> children;
#ManyToOne
#JsonBackReference
private Menu parent;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getCss() {
return css;
}
public void setCss(String css) {
this.css = css;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public Set<Menu> getChildren() {
return children;
}
public void setChildren(Set<Menu> children) {
this.children = children;
}
public Menu getParent() {
return parent;
}
public void setParent(Menu parent) {
this.parent = parent;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
}
Repository
public interface MenuRepository extends JpaRepository<Menu, Long> {
List<Menu> findByActiveTrue();
}
And getting output
[
{
"id": 1,
"menuName": "Customer",
"link": "/customer",
"css": null,
"icon": null,
"active": true,
"children": [
{
"id": 2,
"menuName": "Add Customer",
"link": "/addCustomer",
"css": null,
"icon": null,
"active": false,
"children": []
},
{
"id": 3,
"menuName": "View Customer",
"link": "/viewCustomer",
"css": null,
"icon": null,
"active": false,
"children": []
}
]
}
]
I would do like this:
#Entity
#Table(name = "menu_tbl")
public class Menu {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "menu_description")
private String menuName;
#Column(name = "menu_link", nullable = false)
private String link;
#Column(name = "menu_css")
private String css;
#Column(name = "menu_ico")
private String icon;
#Column(name = "active")
private Boolean active;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "main_id",
nullable = true)
private Menu mainMenu;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "mainMenu", cascade = CascadeType.REMOVE)
private Set<Menu> children = new HashSet<>();
}
And
List<Menu> findAllByMainMenuIdAndActiveIsTrue(Long mainMenuid);
Enable spring-jpa-show-sql=true to watch which queries are being executed against your database from your IDE console. That will give you more insights on how you'll write your method.
Related
I tried to shorten this down to the smallest example I could think of on the fly. In my example I've got store locations by city that are in a state. A store can have a number of fruits. A fruit can be in a number of stores. A fruit can be in a number of states with a cost per state. And a state can have a number of fruits.
I've got five entities: state, store, store_fruit, fruit, and state_fruit as below:
#Entity
#Table(name = "STATE")
public class State {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "STATE_ID")
private Integer stateId;
#Column(name = "STATE_CD")
private String stateCd;
#OneToMany(mappedBy = "state")
private Set<StateFruit> stateFruits;
#OneToMany(mappedBy = "state")
private Set<Store> stores;
public State() {}
#JsonIgnore
public Integer getStateId() {
return stateId;
}
public void setStateId(Integer stateId) {
this.stateId = stateId;
}
#JsonView(Views.Info.class)
#JsonGetter("code")
public String getStateCd() {
return stateCd;
}
public void setStateCd(String stateCd) {
this.stateCd = stateCd;
}
#JsonIgnore
public Set<StateFruit> getStateFruits() {
return stateFruits;
}
public void setStateFruits(Set<StateFruit> stateFruits) {
this.stateFruits = stateFruits;
}
#JsonIgnore
public Set<Store> getStores() {
return stores;
}
public void setStores(Set<Store> stores) {
this.stores = stores;
}
}
#Entity
#Table(name = "STORE")
public class Store {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "STORE_ID")
private Integer storeId;
#Column(name = "STORE_CITY")
private String storeCity;
#OneToMany(mappedBy = "store")
private Set<StoreFruit> storeFruits;
#ManyToOne
#JoinColumn(name = "state_id")
private State state;
public Store() {}
#JsonIgnore
public Integer getStoreId() {
return storeId;
}
public void setStoreId(Integer storeId) {
this.storeId = storeId;
}
#JsonView(Views.Info.class)
#JsonGetter("city")
public String getStoreCity() {
return storeCity;
}
public void setStoreCity(String storeCity) {
this.storeCity = storeCity;
}
#JsonView(Views.Info.class)
#JsonGetter("fruits")
public Set<StoreFruit> getStoreFruits() {
return storeFruits;
}
public void setStoreFruits(Set<StoreFruit> storeFruits) {
this.storeFruits = storeFruits;
}
#JsonView(Views.Info.class)
#JsonGetter("state")
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
#Entity
#Table(name = "STORE_FRUIT")
public class StoreFruit {
#EmbeddedId
private StoreFruitId storeFruitId;
#ManyToOne
#JoinColumn(name = "STORE_ID", insertable = false, updatable = false)
private Store store;
#ManyToOne
#JoinColumn(name = "FRUIT_ID", insertable = false, updatable = false)
private Fruit fruit;
public StoreFruit() {}
#JsonIgnore
public StoreFruitId getStoreFruitId() {
return storeFruitId;
}
public void setStoreFruitId(StoreFruitId storeFruitId) {
this.storeFruitId = storeFruitId;
}
#JsonIgnore
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
#JsonView(Views.Info.class)
#JsonGetter("fruit")
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
#Entity
#Table(name = "FRUIT")
public class Fruit {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FRUIT_ID")
private Integer fruitId;
#Column(name = "FRUIT_NAME")
private String fruitName;
#OneToMany(mappedBy = "fruit")
private Set<StoreFruit> storeFruits;
#OneToMany(mappedBy = "fruit")
private Set<StateFruit> stateFruits;
public Fruit() {}
#JsonIgnore
public Integer getFruitId() {
return fruitId;
}
public void setFruitId(Integer fruitId) {
this.fruitId = fruitId;
}
#JsonView(Views.Info.class)
#JsonGetter("name")
public String getFruitName() {
return fruitName;
}
public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
#JsonIgnore
public Set<StoreFruit> getStoreFruits() {
return storeFruits;
}
public void setStoreFruits(Set<StoreFruit> storeFruits) {
this.storeFruits = storeFruits;
}
#JsonView(Views.Info.class)
#JsonGetter("states")
public Set<StateFruit> getStateFruits() {
return stateFruits;
}
public void setStateFruits(Set<StateFruit> stateFruits) {
this.stateFruits = stateFruits;
}
}
#Entity
#Table(name = "STATE_FRUIT")
public class StateFruit {
#EmbeddedId
private StateFruitId stateFruitId;
#Column(name = "FRUIT_COST")
private Double fruitCost;
#ManyToOne
#JoinColumn(name = "STATE_ID", insertable = false, updatable = false)
private State state;
#ManyToOne
#JoinColumn(name = "FRUIT_ID", insertable = false, updatable = false)
private Fruit fruit;
public StateFruit() {}
#JsonIgnore
public StateFruitId getStateFruitId() {
return stateFruitId;
}
public void setStateFruitId(StateFruitId stateFruitId) {
this.stateFruitId = stateFruitId;
}
#JsonView(Views.Info.class)
#JsonGetter("cost")
public Double getFruitCost() {
return fruitCost;
}
public void setFruitCost(Double fruitCost) {
this.fruitCost = fruitCost;
}
#JsonView(Views.Info.class)
#JsonGetter("state")
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
#JsonIgnore
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
Now when I search my store repository for a store id, I get the following JSON output (using a JsonView):
{
"city": "Fort Worth",
"state": {
"code": "TX"
},
"fruits": [
{
"fruit": {
"name": "Apple",
"states": [
{
"cost": 1.75,
"state": {
"code": "CO"
}
},
{
"cost": 1.5,
"state": {
"code": "TX"
}
}
]
}
},
{
"fruit": {
"name": "Banana",
"states": [
{
"cost": 2.25,
"state": {
"code": "CO"
}
},
{
"cost": 2.0,
"state": {
"code": "TX"
}
}
]
}
}
]
}
It all works as I expect it to, except I'd like to find some way to filter the states set in the fruit section down to the state for the store I'm looking at. Because the store circles around the other way through state to state_fruit I thought I could utilize that relationship, I just haven't come across anything like this yet. Is this possible without having to write a custom query?
I create application in Spring, which stores albums, musicians and bands. Album can contain multiple bands and musicians. I created association between Album and Band/Musician. Jet I am unable to delete it. I don't want to delete objects, just the association. I tried to send REST PUT request and setting musicians and bands to null on Album site, yet nothing happens:
{
"id": 2,
"title": "Lulu",
"bands": null,
"musicians": null,
"duration": {
"hours": 1,
"minutes": 20,
"seconds": 4
},
"releaseDate": "31/10/2011",
"coverPath": "https://upload.wikimedia.org/wikipedia/en/4/40/Lou_Reed_and_Metallica_-_Lulu.jpg",
"spotifyPath": null
}
I have created following class and method to link Album and Musician, yet I am unable to "unlink" them:
#RestController
public class AlbumMusicianController {
#Autowired
AlbumRepository albumRepository;
#Autowired
MusicianRepository musicianRepository;
#Transactional
#PostMapping("/musician/{musicianId}/album/{albumId}")
public List<Album> associate(#PathVariable Long musicianId, #PathVariable Long albumId) {
Album album = this.albumRepository.findById(albumId).orElseThrow(() -> new MissingResourceException("Album",
"Album", albumId.toString()));
return this.musicianRepository.findById(musicianId).map((musician) -> { musician.getAlbums().add(album);
return this.musicianRepository.save(musician).getAlbums();
}).orElseThrow(() -> new MissingResourceException("Musician", "Musician", musicianId.toString()));
}
}
Would be thankful for any help.
Below are necessary sources.
Album class:
#Entity
#Table(name="album")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Album {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="title")
private String title;
#ManyToMany(targetEntity = Band.class, mappedBy = "albums")
#JsonSerialize(using = BandsSerializer.class)
private List<Band> bands;
#ManyToMany(targetEntity = Musician.class, mappedBy = "albums")
#JsonSerialize(using = MusiciansSerializer.class)
private List<Musician> musicians;
#Embedded
#Column(name="duration")
private Duration duration;
#Column(name="releasedate")
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd/MM/yyyy", timezone="CET")
private Date releaseDate;
#Column(name="coverpath")
private String coverPath;
#Column(name="spotifypath")
private String spotifyPath;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Date getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
public String getCoverPath() {
return coverPath;
}
public void setCoverPath(String coverPath) {
this.coverPath = coverPath;
}
public String getSpotifyPath() {
return spotifyPath;
}
public void setSpotifyPath(String spotifyPath) {
this.spotifyPath = spotifyPath;
}
public List<Band> getBands() {
return bands;
}
public void setBands(List<Band> bands) {
this.bands = bands;
}
public List<Musician> getMusicians() {
return musicians;
}
public void setMusicians(List<Musician> musicians) {
this.musicians = musicians;
}
}
Musician class:
#Entity
#Table(name="musician")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Musician {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="name")
private String name;
#Column(name="surname")
private String surname;
#Column(name="birthdate")
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd/MM/yyyy", timezone="CET")
private Date birthDate;
#Column(name="picturepath")
private String picturePath;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "album_musician",
joinColumns = #JoinColumn(name = "album_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "musician_id",
referencedColumnName = "id"))
private List<Album> albums;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getPicturePath() {
return picturePath;
}
public void setPicturePath(String picturePath) {
this.picturePath = picturePath;
}
public List<Album> getAlbums() {
return albums;
}
public void setAlbums(List<Album> albums) {
this.albums = albums;
}
}
Band class:
#Entity
#Table(name="band")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Band {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="name")
private String name;
#Column(name="picturepath")
private String picturePath;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "album_band",
joinColumns = #JoinColumn(name = "album_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "band_id",
referencedColumnName = "id"))
#JsonSerialize(using = AlbumsSerializer.class)
private List<Album> albums;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPicturePath() {
return picturePath;
}
public void setPicturePath(String picturePath) {
this.picturePath = picturePath;
}
public List<Album> getAlbums() {
return albums;
}
public void setAlbums(List<Album> albums) {
this.albums = albums;
}
}
Based on your JSON body I'm going to assume you were sending a PUT request for the Album entity. There were two things that I found missing that got it to work for me after adjusting. I'm not sure if you were avoiding using them for one reason or another.
Cascade rules to cascade changes from Album to its relations.
Proper entity mapping for the join table from Album to its relations.
Not really sure why this was an issue - Hibernate did not seem to throw any exceptions related to this at execution time, but it did not seem to persist things correctly.
Here is an adjusted relation definition for Album's relation to Musician.
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name="album_musician", joinColumns = #JoinColumn(name = "musician_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "album_id",
referencedColumnName = "id"))
private List<Musician> musicians;
In this format, I was able to cascade changes from Album to Musician. You will have to do something similar for the Band entity to cascade operations from Album to Band.
When I send a GET request in POSTMAN to get all my child entity (Town) the parent entity (Province) is not shown in the JSON response.
This is my controller.
#RequestMapping(value ="api/v1/town",method = RequestMethod.GET)
public ResponseEntity<List<Town>> getAllTowns() {
List<Town> towns = townService.getAllTowns();
if(towns.isEmpty()) {
return new ResponseEntity<List<Town>>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<Town>>(towns, HttpStatus.OK);
}
And these are my entities.
Parent Class
#Entity
#Table(name = "PROVINCE")
public class Province {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "PROVINCE_ID")
private long id;
private String name;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "province", targetEntity = Town.class)
#JsonManagedReference("Province-Town")
private List<Town> towns;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Town> getTowns() {
return towns;
}
public void setTowns(List<Town> towns) {
this.towns = towns;
}
}
Child Class
#Entity
#Table(name = "TOWN")
public class Town {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "TOWN_ID")
private long id;
private String name;
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumn(name = "PROVINCE_ID")
#JsonBackReference("Province-Town")
private Province province;
private long kilometer;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
public long getKilometer() {
return kilometer;
}
public void setKilometer(long kilometer) {
this.kilometer = kilometer;
}
}
The response that I'm getting is like this
{
"id" : 1,
"name" : "Some Town",
"kilometer" : 350
}
What I'm expecting is
{
"id" : 1,
"name" : "Some Town",
"province" : {
//Province data.....
}
"kilometer" : 350
}
I was able to show something like this, but the Objects that I used are not Spring-data-jpa entities, just simple POJOs.
Is there any problem with my Entities? Or is there anything else?
Swap #JsonBackReference and #JsonManagedReference. Basically:
#JsonManagedReference
private Province province;
#JsonBackReference
private List<Town> towns;
I have a rest server and client which uses this API. I have a list of hotels and it had passed well until I added bidirectional dependencies to other entities.After that I start receive an endless array of entities which just repeat the same row in database.
It is my first project with hibernate so may be I made trivial mistakes of novice.
Hotel:
#Entity
#Table(name = "hotels", schema = "", catalog = "mydb")
public class HotelsEntity implements HospitalityEntity{
private int idHotel;
private String name;
private String region;
private String description;
// private byte[] photo;
private HotelPropertyEntity property;
private List<RoomEntity> rooms;
#OneToOne(mappedBy = "hotel")
public HotelPropertyEntity getProperty() {
return property;
}
public void setProperty(HotelPropertyEntity property) {
this.property = property;
}
#OneToMany(mappedBy = "hotel")
public List<RoomEntity> getRooms() {
return rooms;
}
public void setRooms(List<RoomEntity> rooms) {
this.rooms = rooms;
}
#Id
#Column(name = "id_hotel", unique = true)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getIdHotel() {
return idHotel;
}
public void setIdHotel(int idHotel) {
this.idHotel = idHotel;
}
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "region")
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
#Basic
#Column(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
HotelProperty
#Entity
#Table(name = "hotel_property", schema = "", catalog = "mydb")
public class HotelPropertyEntity {
private int idHotelProperty;
private byte hasPool;
private byte hasTennisCourt;
private byte hasWaterslides;
private HotelsEntity hotel;
#Id
#Column(name = "id_hotel_property", unique = true)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getIdHotelProperty() {
return idHotelProperty;
}
public void setIdHotelProperty(int idHotelProperty) {
this.idHotelProperty = idHotelProperty;
}
#Basic
#Column(name = "has_pool", columnDefinition = "BIT", length = 1)
public byte getHasPool() {
return hasPool;
}
public void setHasPool(byte hasPool) {
this.hasPool = hasPool;
}
#Basic
#Column(name = "has_tennis_court", columnDefinition = "BIT", length = 1)
public byte getHasTennisCourt() {
return hasTennisCourt;
}
public void setHasTennisCourt(byte hasTennisCourt) {
this.hasTennisCourt = hasTennisCourt;
}
#Basic
#Column(name = "has_waterslides", columnDefinition = "BIT", length = 1)
public byte getHasWaterslides() {
return hasWaterslides;
}
public void setHasWaterslides(byte hasWaterslides) {
this.hasWaterslides = hasWaterslides;
}
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_hotel_property")
public HotelsEntity getHotel() {
return hotel;
}
public void setHotel(HotelsEntity hotel) {
this.hotel = hotel;
}
Room:
#Entity
#Table(name = "room", schema = "", catalog = "mydb")
public class RoomEntity {
private int idRoom;
private String roomType;
private int peopleCapacity;
private Boolean booked;
private Boolean locked;
private HotelsEntity hotel;
private InventoriesEntity inventory;
private RoomPropertyEntity roomProperty;
#OneToOne(mappedBy = "room")
public RoomPropertyEntity getRoom() {
return roomProperty;
}
public void setRoom(RoomPropertyEntity roomProperty) {
this.roomProperty = roomProperty;
}
#OneToOne
#JoinColumn(name = "id_room")
public InventoriesEntity getInventory() {
return inventory;
}
public void setInventory(InventoriesEntity inventory) {
this.inventory = inventory;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_hotel")
public HotelsEntity getHotel() {
return hotel;
}
public void setHotel(HotelsEntity hotel) {
this.hotel = hotel;
}
#Id
#Column(name = "id_room")
public int getIdRoom() {
return idRoom;
}
public void setIdRoom(int idRoom) {
this.idRoom = idRoom;
}
#Basic
#Column(name = "room_type")
public String getRoomType() {
return roomType;
}
public void setRoomType(String roomType) {
this.roomType = roomType;
}
#Basic
#Column(name = "people_capacity")
public int getPeopleCapacity() {
return peopleCapacity;
}
public void setPeopleCapacity(int peopleCapacity) {
this.peopleCapacity = peopleCapacity;
}
#Basic
#Column(name = "booked", columnDefinition = "BIT", length = 1)
public Boolean getBooked() {
return booked;
}
public void setBooked(Boolean booked) {
this.booked = booked;
}
#Basic
#Column(name = "locked", columnDefinition = "BIT", length = 1)
public Boolean getLocked() {
return locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
Could you please advise what is a way or ways to tell hibernate to stop this cycle?
p.s
This code contains another one issue. I f I remove one to one dependency and remain only one to many I receive failed to lazily initialize a collection of role: com.example.model.HotelsEntity.rooms, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.example.model.HotelsEntity["rooms"])
You need to mark entity as not serializable for JSON. Please use #JsonIgnore or #JsonIgnoreProperties("field") on one of the sides of the relations (the annotation is class-level).
I am new to hibernate. I have requirement to introduce the delete functionality in hibernate with annotation. ie once we delete the parent, it needs to delete child records ie i need to introduce the ondelete cascade feature. Could you please help how to introduce this feature. please find below is java/entity code.
#Entity
#Table(name = "atfLabel", uniqueConstraints = #UniqueConstraint(columnNames = {"key_", "module_id"}))
#SuppressWarnings("serial")
public class Label {
private long id;
private ModuleImpl module;
private String key;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#ManyToOne(optional=false)
#JoinColumn(name="module_id", nullable=false, updatable=false)
public ModuleImpl getModule() {
return module;
}
public void setModule(ModuleImpl module) {
this.module = module;
}
#Column(name="key_", length=160)
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
#Entity
#Table(name = "atfModule")
#SuppressWarnings("serial")
public class ModuleImpl implements Module {
private long id;
private String name;
private String description;
#OneToMany(mappedBy="module")
#Cascade(CascadeType.DELETE)
private List<Label> label;
#Override
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Override
#Column(length=200, unique=true, nullable=false)
public String getName() {
return name;
}
#Override
#Column(length=2000)
public String getDescription() {
return description;
}
#Override
public void setName(String name) {
this.name=name;
}
#Override
public void setDescription(String desc) {
this.description=desc;
}
}
#Entity
#Table(name = "atfLabelText",
uniqueConstraints = #UniqueConstraint(columnNames = { "label_id", "tenant_id", "locale" }))
#SuppressWarnings("serial")
public class LabelText {
private long id;
private Label label;
private TenantImpl tenant;
private String locale;
private String text;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
#ManyToOne(optional = false)
#JoinColumn(name = "label_id", nullable = false, updatable = false)
public Label getLabel() {
return label;
}
public String getLocale() {
return locale;
}
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "tenant_id", nullable = true, updatable = false)
public TenantImpl getTenant() {
return tenant;
}
#Column(length = 1500)
public String getText() {
return text;
}
public void setId(long id) {
this.id = id;
}
public void setLabel(Label label) {
this.label = label;
}
public void setLocale(String locale) {
this.locale = locale;
}
public void setTenant(TenantImpl tenant) {
this.tenant = tenant;
}
public void setText(String text) {
this.text = text;
}
}
could you please help me how to do delete functionality and ondelete cascade future.
Thanks
Vijaya Kumar
When you use CascadeType.DELETE:
#OneToMany(mappedBy="module")
#Cascade(CascadeType.DELETE)
private List<Label> label;
It tells Hibernate to navigate the label association and delete persistent instances when an object of ModuleImpl is passed to delete().
Again, if you want to delete any Label persistence instance when it is removed from the label association, you should go with all-delete-orphan:
#OneToMany(orphanRemoval = true, mappedBy = "module")
private List<Label> label;
With all-delete-orphan,any newly instantiated Label becomes persistent if the Label is referenced by a persistent Module. Any persistent Label will be deleted if it’s referenced by an Module when the Module is deleted. And also any persistent Label will be deleted if it’s removed from the label collection of a persistent Module.