Use of #OneToMany or #ManyToMany targeting an unmapped class SpringBoot - java

I am currently learning Spring Boot development with Postgresql.
Everything was going fine up until today when I tried to add one more OneToMany relation in current entity which resulted in Hibernate exception:
Use of #OneToMany or #ManyToMany targeting an unmapped class: com.github.hryniuklukas.Basic_WMS.model.Document.palletList[com.github.hryniuklukas.Basic_WMS.model.Pallet]
Unfortunately current answers on SO give me no hint.
Child class:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDate;
#NoArgsConstructor
#MappedSuperclass
#Entity
#Table(name = "pallet")
#Getter
#Setter
public class Pallet {
private #Id #GeneratedValue(strategy = GenerationType.IDENTITY) Long id;
private String palletCode;
private LocalDate date;
private boolean isInWarehouse;
public Pallet(String palletCode, LocalDate date){
this.palletCode=palletCode;
this.date = date;
this.isInWarehouse = true;
}
#ManyToOne(fetch = FetchType.LAZY)
private PalletSpace palletSpace;
#ManyToOne(fetch = FetchType.LAZY)
private Document outboundDocument;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Pallet )) return false;
return id != null && id.equals(((Pallet) o).getId());
}
public void setPalletStatusAsSent(){
this.isInWarehouse = false;
}
#Override
public int hashCode() {
return getClass().hashCode();
}
}
Parent 1:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#NoArgsConstructor
#Getter
#Setter
#Entity(name = "PalletSpace")
#Table(name = "pallet_space")
public class PalletSpace {
private #Id #GeneratedValue (strategy = GenerationType.IDENTITY) Long id;
private String spaceCode;
#OneToMany(
mappedBy = "palletSpace",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Pallet> palletList = new ArrayList<>();
public PalletSpace(String spaceCode){
this.spaceCode = spaceCode;
}
public void addPallet(Pallet pallet){
palletList.add(pallet);
pallet.setPalletSpace(this);
}
public void removePallet(Pallet pallet){
palletList.remove(pallet);
pallet.setPalletSpace(null);
}
}
Parent 2:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#NoArgsConstructor
#Getter
#Setter
#Slf4j
#Entity
#Table(name = "document")
public class Document {
private #Id #GeneratedValue(strategy = GenerationType.IDENTITY) Long id;
#OneToMany(
mappedBy = "outboundDocument",
cascade = CascadeType.PERSIST
)
private List<Pallet> palletList = new ArrayList<>();
public void addPalletToDocument(Pallet pallet) {
palletList.add(pallet);
pallet.setOutboundDocument(this);
}
public List<Pallet> getConnectedPalletList() {
return this.palletList;
}
public void removePalletFromDocument(Pallet pallet) {
palletList.remove(pallet);
pallet.setOutboundDocument(null);
}
public void executeDocument() {
palletList.forEach(Pallet::setPalletStatusAsSent);
}
}
Pallet in relation to palletspace worked fine, adding Document to the mix results in exception.
JPA Buddy seems to catch the relations just as it should, showing reference tree correctly, Spring doesnt start thou.
Application properties:
spring.datasource.url=jdbc:postgresql://localhost:5050/postgres
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}
spring.datasource.driverClassName=org.postgresql.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

Try removing #MappedSuperclass from Pallet, since it shouldn't be mixed with #Entity

Related

How to fix JPA in Spring Boot error IllegalStateException: The column type is undefined?

I am using JPA + Spring Boot for my project. This is the first time I'm using JPA and I'm also very new to Spring Boot.
I want to create two tables file_perms and file_perm_values. I am able to get the definition of file_perms right. However, for my second table file_perm_values, I want to define a composite primary key that consists of the primary key of the file_perms, i.e., id and another String file_id. When I write the definition shown below and use the DDL creation button of Intellij, I get the error Caused by: java.lang.IllegalStateException: The column type is undefined. Table - file_perm_values; Column - file_perm_id
What am I doing wrong?
Could some of the experts out there please help me understand what's the problem and how to fix this?
I'll be very grateful
package com.some.project.persistence.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.ZonedDateTime;
import java.util.UUID;
#Entity
#Getter
#Builder
#NoArgsConstructor
#AllArgsConstructor
#ToString(onlyExplicitlyIncluded = true)
#Table(name = "file_perms")
public class FilePermsEntity {
#Id
#GeneratedValue
#Builder.Default
#ToString.Include
#Column(name = "id", nullable = false)
private UUID id = null;
#ToString.Include
#Column(name = "perm_name", nullable = false)
private String permName;
#ToString.Include
#Column(name = "is_active", nullable = false)
private boolean active;
#ToString.Include
#Column(name = "perm_guid")
private String permGuid;
#ToString.Include
#Column(name = "perm_index")
private int permIndex;
#CreatedDate
#Builder.Default
#ToString.Include
#Column(name = "created_at")
private ZonedDateTime createdAt = ZonedDateTime.now();
#Builder.Default
#ToString.Include
#LastModifiedDate
#Column(name = "updated_at")
private ZonedDateTime updatedAt = ZonedDateTime.now();
}
package com.some.project.persistence.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import java.io.Serializable;
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder
#ToString(onlyExplicitlyIncluded = true)
#Table(name = "file_perm_values")
public class FilePermValuesEntity {
#EmbeddedId
#ToString.Include
private FilePermValuesPrimaryKey id;
#ToString.Include
#Column(name = "value")
private String value;
#Getter
#Builder
#Embeddable
#NoArgsConstructor
#AllArgsConstructor
#ToString(onlyExplicitlyIncluded = true)
public static class FilePermValuesPrimaryKey implements Serializable {
private static final long serialVersionUID = 1223232L;
#MapsId
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "file_perm_id", nullable = false)
private FilePermsEntity filePermsEntity;
#ToString.Include
#Column(name = "file_id", nullable = false)
private String fileId;
#Override
public boolean equals(Object o) {
...
}
#Override
public int hashCode() {
...
}
}
}
The code below solved my problem:
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder
#ToString(onlyExplicitlyIncluded = true)
#Table(name = "file_perm_values")
public class FilePermValuesEntity {
#EmbeddedId
#ToString.Include
private FilePermValuesPrimaryKey id;
#MapsId("filePermId")
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "file_perm_id")
private FilePermsEntity filePermsEntity;
#ToString.Include
#Column(name = "value")
private String value;
#Getter
#Builder
#Embeddable
#NoArgsConstructor
#AllArgsConstructor
#ToString(onlyExplicitlyIncluded = true)
public static class FilePermValuesPrimaryKey implements Serializable {
private static final long serialVersionUID = 1223232L;
#ToString.Include
#Column(name = "file_perm_id", nullable = false)
private UUID filePermId;
#ToString.Include
#Column(name = "file_id", nullable = false)
private String fileId;
#Override
public boolean equals(Object o) {
...
}
#Override
public int hashCode() {
...
}
}
}

Spring JPA - Removing all child entities instead of one

I have a Spring Boot app that uses Spring JPA which performs actions on a parent/child, OneToMany database relationship. I have been perfoming save and get requests without issue for a while however I now have a need to remove a child entity from the child database table, however when I test my code I find it removes all child entities from the DB AND the parent entity which is not the behaviour I am looking for.
Below are the entity classes, Zoo is the parent, and Animal is the child. They should have a oneToMany relation.
The parent entity.
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import com.fasterxml.jackson.annotation.JsonManagedReference;
#Entity
#Table(name = "ZOOS")
public class Zoo {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true)
private Integer id;
#ManyToOne
#JoinColumn(name="name")
private String name;
#OneToMany(mappedBy = "zoo", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#Fetch(value = FetchMode.SUBSELECT)
#JsonManagedReference
private List<Animal> animal;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Animal> getAnimal() {
return animal;
}
public void setAnimal(List<Animal> animal) {
this.animal = animal;
}
}
The child entity
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonBackReference;
#Entity
#Table(name = "ANIMALS")
public class Animal {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true)
private Integer id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "zooId")
#JsonBackReference
private Zoo zoo;
#Column(name = "species", nullable = false)
private String species;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Zoo getZoo() {
return zoo;
}
public void setZoo(Zoo zoo) {
this.zoo = zoo;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
}
The repo for the Animal (child) entity
import org.springframework.data.jpa.repository.JpaRepository;
import uk.co.example.api.entities.Animal;
public interface AnimalRepository extends JpaRepository<Animal, Integer> {
}
The java method being called to delete the animal entity
#Autowired
AnimalRepository animalRepo;
public void deleteAnimal(Integer animalId) {
animalRepo.deleteById(animalId);
}
The method should remove one animal from the Animal db table, however in practice it is removing ALL animals with the same zooId and the zoo from the Zoo db table.
I have researched and tried changing the CascadeType.ALL on the ManyToOne annotation in the Animal entity class to PERSIST and I've tried removing the cascade parameter altogether, in both cases I found I would get no errors in my app but no animal records would be removed at all. The tables would be in the same state as before the method was run.
I have also tried using 'orphanRemoval = true' on the OneToMany annotation on the Zoo entity class however this doesn't seem to have any impact when testing.
#OneToMany(mappedBy = "zoo", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
#Fetch(value = FetchMode.SUBSELECT)
#JsonManagedReference
private List<Animal> animal;
Any help will be appreciated.
The relationship from Animal to Zoo is wrong
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "zooId")
#JsonBackReference
private Zoo zoo;
With CascateType.ALL if you delete an Animal also, the Zoo will be deleted, and this will issue to delete all animals.
You should remove the cascading because it in most cases doesn't make sense

Spring Boot - created_at cannot be null. Spring JPA

Whenever I am trying to save an object to my DB, I keep getting the error Column 'created_at' cannot be null.
Here is my audit model:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(
value = {"createdAt", "updatedAt"},
allowGetters = true
)
public abstract class AuditModel implements Serializable {
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
#Column(name = "created_at", nullable = false, updatable = false)
#JsonIgnore
private Date createdAt;
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
#Column(name = "updated_at", nullable = false)
private Date updatedAt;
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
}
Here is an example of a model that extends it:
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.lang.Nullable;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Set;
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
public class Category extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotEmpty(message = "Item Name is required.")
private String categoryName;
#NotNull
private String categoryDescription;
#Nullable
#JsonIgnore
#OneToMany(mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<Item> items;
public Category(String categoryName, String categoryDescription) {
this.categoryName = categoryName;
this.categoryDescription = categoryDescription;
}
And here is the temporary CommandLine bean that is performing some tests for me:
#Configuration
public class ItemConfig {
#Autowired
ItemRepository itemRepository;
#Autowired
CategoryRepository categoryRepository;
#Value("${STORE.ENV}")
private String env;
#Bean
CommandLineRunner itemRunner(ItemRepository itemRepository) {
return args -> {
System.out.println("true");
Category cueCategory = new Category
("Cues",
"This category contains all items relating to billiard cues. This includes yada, yadada, and yada."
);
categoryRepository.save(cueCategory);
Item item = new Item("Test Cue", 700, cueCategory);
itemRepository.save(item);
};
}
}
At first, I was creating a blank object then setting all the values with setters. I thought that maybe it all needed to happen in one fel-swoop for the created_at to register with a proper date, so I added some constructors. That still didn't work. Please let me know if you see anything glaring!
You can fix this issue by modifying your createdAt and updatedAt properties like below and also, modify your getter and setters.
#CreationTimestamp
#Column(name = "created_at", updatable = false)
private Timestamp createdAt;
#UpdateTimestamp
#Column(name = "updated_at")
private Timestamp updatedAt;
You should add #EnableJpaAuditing annotation.
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
// ...
#Configuration
#EnableJpaAuditing
public class ItemConfig {
// ...
}

Java Spring TransientPropertyValueException with #OneToMany

I have the following classes:
A Product class:
package com.springtraining.hibernate.invoice;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
#NoArgsConstructor
#Getter
#Entity
#Table(name="PRODUCTS")
public class Product {
#Id
#GeneratedValue
#NotNull
#Column(name = "ID")
private int id;
#Column(name = "NAME")
private String name;
#OneToMany(
targetEntity = Item.class,
mappedBy = "product",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY
)
private List<Item> items = new ArrayList<>();
public Product(String name) {
this.name = name;
}
}
package com.springtraining.hibernate.invoice.dao;
import com.springtraining.hibernate.invoice.Product;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
#Repository
#Transactional
public interface ProductDao extends CrudRepository<Product, Integer> {
}
Now, an Item class:
package com.springtraining.hibernate.invoice;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
#NoArgsConstructor
#Getter
#Entity
#Table(name="ITEMS")
public class Item {
#Id
#GeneratedValue
#NotNull
#Column(name = "ID")
private int id;
#JoinColumn(name = "PRODUCT_ID", referencedColumnName = "id")
#ManyToOne
private Product product;
#NotNull
#Column(name = "PRICE")
private BigDecimal price;
#NotNull
#Column(name = "QUANTITY")
private int quantity;
#NotNull
#Column(name = "VALUE")
private BigDecimal value;
#JoinColumn(name="INVOICE_ID", referencedColumnName = "id")
#ManyToOne
private Invoice invoice;
public Item(Product product, String price, int quantity) {
this.product = product;
this.product.getItems().add(this);
this.price = new BigDecimal(price);
this.quantity = quantity;
this.value = this.price.multiply(new BigDecimal(quantity));
}
public void setInvoice(Invoice invoice) {
this.invoice = invoice;
invoice.getItems().add(this);
}
}
package com.springtraining.hibernate.invoice.dao;
import com.springtraining.hibernate.invoice.Item;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
#Repository
#Transactional
public interface ItemDao extends CrudRepository<Item, Integer> {
}
And an Invoice class:
package com.springtraining.hibernate.invoice;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
#NoArgsConstructor
#Getter
#Entity
#Table(name="INVOICES")
public class Invoice {
#Id
#GeneratedValue
#NotNull
#Column(name = "ID")
private int id;
#NotNull
#Column(name = "NUMBER")
private String number;
#OneToMany(
targetEntity = Item.class,
mappedBy = "invoice",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY
)
private List<Item> items = new ArrayList<>();
public Invoice(String number) {
this.number = number;
}
}
package com.springtraining.hibernate.invoice.dao;
import com.springtraining.hibernate.invoice.Invoice;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
#Repository
#Transactional
public interface InvoiceDao extends CrudRepository<Invoice, Integer> {
}
Now, when I am running a unit test with these classes, I get the following error:
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.springtraining.hibernate.invoice.Item.product -> com.springtraining.hibernate.invoice.Product; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.springtraining.hibernate.invoice.Item.product -> com.springtraining.hibernate.invoice.Product
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.springtraining.hibernate.invoice.Item.product -> com.springtraining.hibernate.invoice.Product; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.springtraining.hibernate.invoice.Item.product -> com.springtraining.hibernate.invoice.Product
The unit test code looks like such:
package com.springtraining.hibernate.invoice.dao;
import com.springtraining.hibernate.invoice.Invoice;
import com.springtraining.hibernate.invoice.Item;
import com.springtraining.hibernate.invoice.Product;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
#RunWith(SpringRunner.class)
#SpringBootTest
public class InvoiceDaoTestSuite {
#Autowired
private InvoiceDao invoiceDao;
#Test
public void testInvoiceDaoSave() {
// Given
Product product1 = new Product("prod1");
Product product2 = new Product("prod2");
Item item1 = new Item(product1, "100", 10);
Item item2 = new Item(product1, "200", 10);
Item item3 = new Item(product2, "50", 2);
Item item4 = new Item(product2, "250", 25);
Invoice invoice1 = new Invoice("HK-47");
item2.setInvoice(invoice1);
item3.setInvoice(invoice1);
Invoice invoice2 = new Invoice("HK-48");
item1.setInvoice(invoice2);
item4.setInvoice(invoice2);
// When
invoiceDao.save(invoice1);
invoiceDao.save(invoice2);
int invoice1_id = invoice1.getId();
int invoice2_id = invoice2.getId();
// Then
Assert.assertNotEquals(0, invoice1_id);
Assert.assertNotEquals(0, invoice2_id);
Assert.assertTrue(invoice1.getItems().containsAll(Arrays.asList(item2, item3)));
Assert.assertTrue(invoice2.getItems().containsAll(Arrays.asList(item1, item4)));
Assert.assertTrue(product1.getItems().containsAll(Arrays.asList(item1, item2)));
Assert.assertTrue(product1.getItems().containsAll(Arrays.asList(item3, item4)));
// Clean-up
try {
invoiceDao.deleteById(invoice1_id);
invoiceDao.deleteById(invoice2_id);
} catch (Exception e) {
// Do nothing
}
}
}
I have been looking at this code for a few hours now, and I still do not get it, where I have missed something. Saving Invoice entity, should automatically instantiate Item and Product objects associated with it as well.
Anyone?
In public class Item, add #ManyToOne cascade = CascadeType.ALL property, like so:
#JoinColumn(name = "PRODUCT_ID", referencedColumnName = "id")
#ManyToOne(cascade = CascadeType.ALL)
private Product product;
#JoinColumn(name = "INVOICE_ID", referencedColumnName = "id")
#ManyToOne(cascade = CascadeType.ALL)
private Invoice invoice;
When you create a new entity, using the keyword new, it is in the Transient state. To persist/save it to the DB, you first need to add it to the Persistence Context. CascadeType.ALL includes CascadeType.PERSIST, which will instruct Hibernate to persist the product and invoice entities.
Also, remove the #NotNull on your entity fields annotated by #Id. It is not required, since your field is a primary key and instead of this
invoiceDao.save(invoice1);
invoiceDao.save(invoice2);
int invoice1_id = invoice1.getId();
int invoice2_id = invoice2.getId();
You can do:
int invoice1_id = invoiceDao.save(invoice1).getId();
int invoice2_id = invoiceDao.save(invoice2).getId();

Why mapped list is empty?

I am new with hibernate and jpa. I need a little help. I'm developing a restful service application with spring boot. Using mysql and hibernate.
When i call my service "ingredients" array will be empty like that.
Empty array
In database ingredient table and recipe table has one to many relationship so i tried to do same thing with JPA but i can't find correct way. When I try to get Recipe i can access but ingredient list is always empty.
My Database Design:
DB Design
Recipe Entity:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity()
#Table(name="recipe")
#Getter
#Setter
public class Recipe {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "recipe_id")
private int recipeId;
#Column(name ="name")
private String name;
#Column(name = "description")
private String description;
#Column(name = "picture_id")
private int pictureId;
#OneToMany(mappedBy = "recipe",fetch = FetchType.EAGER)
private List<Ingredient> ingredients = new ArrayList<>();
}
Ingredient Entitiy:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.io.Serializable;
#Entity()
#Table(name = "ingredient")
#Getter
#Setter
public class Ingredient implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ingredient_id")
private int ingredientId;
#Column(name = "scale")
private String scale;
#ManyToOne
#JoinColumn(name = "recipe_id",nullable = false)
private Recipe recipe;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "material_id",nullable = false)
private Material material;
}
RecipeDAO:
import com.mutfak.dolapservice.dao.interfaces.IRecipeDAO;
import com.mutfak.dolapservice.entity.Recipe;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
#Transactional
#Repository
public class RecipeDAO implements IRecipeDAO {
#PersistenceContext
private EntityManager entityManager;
#SuppressWarnings("unchecked")
#Override
public List<Recipe> getRecipes() {
String query = "FROM Recipe ORDER BY recipe_id";
return (List<Recipe>) entityManager.createQuery(query).getResultList();
}
#Override
public Recipe getRecipeByMaterial(int materialId) {
return null;
}
#Override
public Recipe getRecipeById(int id) {
return null;
}
#Override
public void addRecipe(Recipe recipe) {
}
#Override
public void updateRecipe(Recipe recipe) {
}
#Override
public void deleteRecipe(int id) {
}
}
Finally I find solution. Lombok annotation's and JPA doesn't work correctly. JPA can't get List<> with Lombok.

Categories

Resources