POST request with Many-to-many relationship in Spring Data REST - spring

I'm trying to add a movie to MySQL database, here's my database schema:
Movie(id, name)
Genre(id, name)
Movie_genre(id_movie, id_genre)
And here's my model classes:
Movie.ts
public class Movie {
private Short id;
private String name;
private List<MovieGenre> movieGenres;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
public Short getId() {
return id;
}
public void setId(Short id) {
this.id = id;
}
#Column(name = "name", nullable = false, length = 100)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(mappedBy = "movie")
public List<MovieGenre> getMovieGenres() {
return movieGenres;
}
public void setMovieGenres(List<MovieGenre> movieGenres) {
this.movieGenres = movieGenres;
}
}
Genre.ts
public class Genre {
private Short id;
private String name;
private List<MovieGenre> movieGenres;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
public Short getId() {
return id;
}
public void setId(Short id) {
this.id = id;
}
#Column(name = "name", nullable = false, length = 15)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(mappedBy = "genre")
#JsonIgnore
public List<MovieGenre> getMovieGenres() {
return movieGenres;
}
public void setMovieGenres(List<MovieGenre> movieGenres) {
this.movieGenres = movieGenres;
}
}
MovieGenre.ts ( that model stands for the generated table )
public class MovieGenre {
private MovieGenrePK id;
private Movie movie;
private Genre genre;
#EmbeddedId
#JsonIgnore
public MovieGenrePK getId() {
return id;
}
public void setId(MovieGenrePK id) {
this.id = id;
}
#MapsId("movieId")
#ManyToOne
#JoinColumn(name = "movie_id", referencedColumnName = "id", nullable = false)
#JsonIgnore
public Movie getMovie() {
return movie;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
#MapsId("genreId")
#ManyToOne
#JoinColumn(name = "genre_id", referencedColumnName = "id", nullable = false)
public Genre getGenre() {
return genre;
}
public void setGenre(Genre genre) {
this.genre = genre;
}
}
and because we have composite key in the last model, we need a class for that :
public class MovieGenrePK implements Serializable {
private Short movieId;
private Short genreId;
#Column(name = "movie_id", nullable = false)
public Short getMovieId() {
return movieId;
}
public void setMovieId(Short movieId) {
this.movieId = movieId;
}
#Column(name = "genre_id", nullable = false)
public Short getGenreId() {
return genreId;
}
public void setGenreId(Short genreId) {
this.genreId = genreId;
}
}
So I'm trying to add a movie with genres by making a post request, first i made a post request for adding a movie and another one for adding a genre, that's works fine, now i need to associate a genre to a movie.
I tried the following:
I made a POST request to the following endpoint: http://localhost:8080/api/movieGenres with application/json header and with the following body:
{
"movie": "http://localhost:8080/api/movies/6",
"genre": "http://localhost:8080/api/genres/1"
}
but i got the error:
{
"timestamp": "2018-08-22T21:10:30.830+0000",
"status": 500,
"error": "Internal Server Error",
"message": "NullPointerException occurred while calling setter of com.movies.mmdbapi.model.MovieGenrePK.genreId; nested exception is org.hibernate.PropertyAccessException: NullPointerException occurred while calling setter of com.movies.mmdbapi.model.MovieGenrePK.genreId",
"path": "/api/movieGenres"
}

You have to instatiate MovieGenrePK, change:
public class MovieGenre {
private MovieGenrePK id;
}
to
public class MovieGenre {
private MovieGenrePK id = new MovieGenrePK();
}

Related

Many to One Relationship with #IdClass

Using Spring Data JPA & Hibernate, I am saving an object Company, that has 0 to Many AccountMapping. The AccountMappings Primary Key is a composite of a String accountNumber and the Company Primary Key. When I save a new company the COMP_NUM from the Company Object is not set into the AccountMapping object. When I use long companyNumber it is zero, and Long it is NUM. Hibernate is executing the insert statement first, but how to get it to set the primary key from company into child object ?
#Entity
#Table(name = "COMPANY")
public class Company implements Serializable {
#Id
#Column(name = "COMP_NUM")
#SequenceGenerator(name = "comp_num_seq", sequenceName = "comp_num_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "comp_num_seq")
private long number;
#OneToMany(mappedBy = "companyNumber", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<AccountMapping> accountMappings;
public Company() {
super();
}
public long getNumber() {
return this.number;
}
public void setNumber(long id) {
this.number = id;
}
public List<AccountMapping> getAccountMappings() {
return accountMappings;
}
public void setAccountMappings(List<AccountMapping> accountMappings) {
this.accountMappings = accountMappings;
}
}
#Entity
#IdClass(value = AccountMappingPK.class)
#Table(name = "ACCOUNT_MAPPING")
public class AccountMapping implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ACCNT_NUM")
private String accountNumber;
#Id
#Column(name = "COMP_NUM")
private Long companyNumber;
#Column(name = "IS_PRIMARY")
private Boolean isPrimary;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public Long getCompanyNumber() {
return companyNumber;
}
public void setCompanyNumber(Long companyNumber) {
this.companyNumber = companyNumber;
}
public Boolean getIsPrimary() {
return isPrimary;
}
public void setIsPrimary(Boolean isPrimary) {
this.isPrimary = isPrimary;
}
}
public class AccountMapping implements Serializable {
#Column(name = "EA_ACCNT_NUM", nullable = false)
private String accountNumber;
#Column(name = "COMP_NUM", nullable = false)
private Long companyNumber;
public AccountMapping() {
// default constructor
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNum(String accountNumber) {
this.accountNumber = accountNumber;
}
public Long getCompanyNumber() {
return companyNumber;
}
public void setCompanyNumber(Long companyNumber) {
this.companyNumber = companyNumber;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof AccountMappingPK) {
AccountMappingPK accntPk = (AccountMappingPK) obj;
if (!(accountNumber.equals(accntPk.getAccountNumber()))) {
return false;
}
if (!(accntPk.getCompanyNumber() == (companyNumber))) {
return false;
}
return true;
}
return false;
}
#Override
public int hashCode() {
int hash = (accountNumber == null ? 1 : accountNumber.hashCode());
return (int) (hash * companyNumber);
}
}
#Entity
#IdClass(value = AccountMappingPK.class)
#Table(name = "ACCOUNT_MAPPING")
public class AccountMapping implements Serializable {
#Id
#Column(name = "ACCNT_NUM")
private String accountNumber;
#Id
#ManyToOne
#JoinColumn(name = "COMP_NUM")
private Company company;
...
}
// No annotations in this class
public class AccountMappingPK implements Serializable {
private String accountNumber;
private Company company;
...
// All the getter/setter, constructors, and so on ...
}
The Hibernate ORM documentation has more details about mapping with #IdClass: See Example 134. IdClass with #ManyToOne

Error mapping OneToMany or ManyToOne unmapped class

I have this problem :
Error creating bean with name 'ICustomerDao' defined in com.biblio.fr.biblio.repository.ICustomerDao defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: com.biblio.fr.biblio.entite.Book.loans[com.biblio.fr.biblio.entite.Loan]
this is my code :
#Entity
#Table(name = "BOOK")
public class Book {
private Integer id;
private String title;
private String isbn;
private LocalDate releaseDate;
private LocalDate registerDate;
private Integer totalExamplaries;
private String author;
private Category category;
Set<Loan> loans = new HashSet<Loan>();
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "BOOK_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "TITLE", nullable = false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "ISBN", nullable = false, unique = true)
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
#Column(name = "RELEASE_DATE", nullable = false)
public LocalDate getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(LocalDate releaseDate) {
this.releaseDate = releaseDate;
}
#Column(name = "REGISTER_DATE", nullable = false)
public LocalDate getRegisterDate() {
return registerDate;
}
public void setRegisterDate(LocalDate registerDate) {
this.registerDate = registerDate;
}
#Column(name = "TOTAL_EXAMPLARIES")
public Integer getTotalExamplaries() {
return totalExamplaries;
}
public void setTotalExamplaries(Integer totalExamplaries) {
this.totalExamplaries = totalExamplaries;
}
#Column(name = "AUTHOR")
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
#ManyToOne(optional = false)
#JoinColumn(name = "CAT_CODE", referencedColumnName = "CODE")
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
// #OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.book", cascade =
// CascadeType.ALL)
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk", cascade = CascadeType.ALL)
public Set<Loan> getLoans() {
return loans;
}
public void setLoans(Set<Loan> loans) {
this.loans = loans;
}
}
public class Loan implements Serializable {
private static final long serialVersionUID = 144293603488149743L;
private LoanId pk = new LoanId();
private LocalDate beginDate;
private LocalDate endDate;
private LoanStatus status;
#EmbeddedId
public LoanId getPk() {
return pk;
}
public void setPk(LoanId pk) {
this.pk = pk;
}
#Column(name = "BEGIN_DATE", nullable = false)
public LocalDate getBeginDate() {
return beginDate;
}
public void setBeginDate(LocalDate beginDate) {
this.beginDate = beginDate;
}
#Column(name = "END_DATE", nullable = false)
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
#Enumerated(EnumType.STRING)
#Column(name = "STATUS")
public LoanStatus getStatus() {
return status;
}
public void setStatus(LoanStatus status) {
this.status = status;
}
}
#Embeddable
public class LoanId implements Serializable {
private static final long serialVersionUID = 3912193101593832821L;
private Book book;
private Customer customer;
private LocalDateTime creationDateTime;
public LoanId() {
super();
}
public LoanId(Book book, Customer customer) {
super();
this.book = book;
this.customer = customer;
this.creationDateTime = LocalDateTime.now();
}
#ManyToOne
public Book getBook() {
return book;
}
public void setBook(Book bbok) {
this.book = bbok;
}
#ManyToOne
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
#Column(name = "CREATION_DATE_TIME")
public LocalDateTime getCreationDateTime() {
return creationDateTime;
}
public void setCreationDateTime(LocalDateTime creationDateTime) {
this.creationDateTime = creationDateTime;
}
}
#Table(name = "CUSTOMER")
public class Customer {
private Integer id;
private String firstName;
private String lastName;
private String job;
private String address;
private String email;
private LocalDate creationDate;
Set<Loan> loans = new HashSet<Loan>();
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "CUSTOMER_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "FIRST_NAME", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "LAST_NAME", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "JOB")
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
#Column(name = "ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "EMAIL", nullable = false, unique = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "CREATION_DATE", nullable = false)
public LocalDate getCreationDate() {
return creationDate;
}
public void setCreationDate(LocalDate creationDate) {
this.creationDate = creationDate;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.customer", cascade = CascadeType.ALL)
public Set<Loan> getLoans() {
return loans;
}
public void setLoans(Set<Loan> loans) {
this.loans = loans;
}
}
public class Category {
public Category() {
}
public Category(String code, String label) {
super();
this.code = code;
this.label = label;
}
private String code;
private String label;
#Id
#Column(name = "CODE")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name = "LABEL", nullable = false)
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
#Repository
public interface ICategoryDao extends JpaRepository<Category, Integer> {
}
public interface ICustomerDao extends JpaRepository<Customer, Integer> {
public Customer findCustomerByEmailIgnoreCase(String email);
public List<Customer> findCustomerByLastNameIgnoreCase(String lastName);
}
I can't see where is the problem of my oneTomany annotation
Anyone can, i help me.

Not null reference a null or transient value

So i am trying to achieve oneToone relationship between two entity classes.First class is a customer entity class which have two foreign keys buyer_id and seller_id.So what i want initially is that when the user fills the initial credentials in the website the buyer_id and seller_id field should be null and after the user fills the required information for the buyer or seller i will update the row of the corresponding customer and add the buyer_id and seller_id.But when i try to create a customer entry i am getting this error that buyer_id cannot be null?
This is my customer table
#Entity
#Table(name = "Customer")
public class Customer {
public enum Status{
ACTIVE,
IN_ACTIVE
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#OneToOne(fetch = FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "seller_id",nullable = true,referencedColumnName = "id",updatable = true)
#Basic(optional = true)
private Seller seller_id;
#OneToOne(fetch=FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "buyer_id", nullable = true,referencedColumnName="id",updatable = true)
#Basic(optional = true)
private Buyer buyer_id;
#OneToOne(fetch=FetchType.LAZY,optional = false,cascade = CascadeType.ALL)
#JoinColumn(name = "user_id",nullable = false,unique = true,referencedColumnName = "id")
private User user_id;
public Buyer getBuyer_id() {
return buyer_id;
}
public void setBuyer_id(Buyer buyer_id) {
this.buyer_id = buyer_id;
}
#Column(name = "Name")
String name;
#Enumerated(EnumType.STRING)
#Column(name = "Status")
private Status status;
public Customer(String name,Status status){
this.name=name;
this.status = status;
}
public Customer(){
}
public Seller getSeller_id() {
return seller_id;
}
public void setSeller_id(Seller seller_id) {
this.seller_id = seller_id;
}
public User getUser_id() {
return user_id;
}
public void setUser_id(User user_id) {
this.user_id = user_id;
}
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 User getUser() {
return user_id;
}
public void setUser(User user) {
this.user_id = user;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
This is my buyer table
#Entity
#Table(name="Buyer")
public class Buyer {
#Id
#Column(name = "id") private long id;
#Column(name = "GSTIN")
String GSTIN;
#Column(name = "Legal_Document")
#Lob
private byte[] legalDocument;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "buyer_id")
#JsonIgnore
private Customer customer;
#Column(name = "Authorized_person_name")
String authorized_person_name;
#Column(name = "Authorized_person_email")
String authorized_person_email;
}
This is my seller table
#Entity
#Table(name = "Seller")
public class Seller {
#Id
#Nullable
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "GSTIN")
private String GSTIN;
#Column(name = "GST_Document")
#Lob
private byte[] gst_document;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "seller_id")
#JsonIgnore
private Customer customer;
// #OneToOne(fetch = FetchType.LAZY,
// cascade = CascadeType.ALL,
// mappedBy = "sellerId")
// #JsonIgnore
// private PickupAddress pickupAddress;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
public String getGSTIN() {
return GSTIN;
}
public void setGSTIN(String GSTIN) {
this.GSTIN = GSTIN;
}
public byte[] getGst_document() {
return gst_document;
}
public void setGst_document(byte[] gst_document) {
this.gst_document = gst_document;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

JAVA 8 - Stream features giving error while retriving data from 3 POJO class

I am having 3 POJO class for products, attribute & value. All three POJOs are have relationship with other POJO class. Now, I want to retrive value for the
each and every products.
It was working perfectly with the older approach but now i want to modify my code with new JAVA 8 features.
Please find my code below.
listProducts.stream().forEachOrdered(listproducts ->
listproducts.getProductAttr()
.stream().forEachOrdered(attr ->
(((Collection<ProductAttrValue>) attr.getProductAttrValue()
.stream().filter(attrlabel ->
attrlabel.getLabel().equalsIgnoreCase("source"))))
.stream().forEachOrdered(attrval ->
{
System.out.println(attrval.getValue());
}
)
)
);
Please find the error message that I am getting.
Exception in thread "main" java.lang.ClassCastException:
java.util.stream.ReferencePipeline$2 cannot be cast to java.util.Collection
at Hibernate.Testing.App.lambda$1(App.java:81)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown
Source)
at java.util.stream.ReferencePipeline$Head.forEachOrdered(Unknown Source)
at Hibernate.Testing.App.lambda$0(App.java:81)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.ReferencePipeline$Head.forEachOrdered(Unknown Source)
at Hibernate.Testing.App.main(App.java:80)
If am not doing type casting .stream().forEachOrdered(attr -> ((Collection<ProductAttrValue>) attr.getProductAttrValue() am getting the below errors.
Please find my Product POJO class
public class Product {
private String name;
private long std_delivery_Time;
private int min_order_Quantity;
private String status;
private long catalog_Id;
private Date expiration_Date;
private int rank;
private String product_Type;
private int is_Visible;
private String product_Group;
private String code;
#Id
#Column(name = "ID")
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#OneToMany( mappedBy = "product", cascade = CascadeType.ALL)
private List<ProductAttr> productAttr;
public List<ProductAttr> getProductAttr() {
return productAttr;
}
public void setProductAttr(List<ProductAttr> productAttr) {
this.productAttr = productAttr;
}
}
ProductAttr class
public class ProductAttr {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", updatable=false, nullable=false)
private long id;
#Column(name = "NAME")
private String name;
#Column(name = "PRODUCT_ID")
private long product_id;
public ProductAttr() {
super();
// TODO Auto-generated constructor stub
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getProduct_id() {
return product_id;
}
public void setProduct_id(long product_id) {
this.product_id = product_id;
}
public long getId() {
return id;
}
#ManyToOne
#JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID",
insertable = false, updatable = false)
private Product product;
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
#OneToMany( mappedBy = "productAttr", cascade = CascadeType.ALL)
private Set<ProductAttrValue> productAttrValue;
public Set<ProductAttrValue> getProductAttrValue() {
return productAttrValue;
}
public void setProductAttrValue(Set<ProductAttrValue>
productAttrValue) {
this.productAttrValue = productAttrValue;
}
}
ProductValue class
public class ProductAttrValue {
#Id
#Column(name = "ATTR_ID", updatable=false, nullable=false)
private long attr_id;
#Column(name = "LABEL")
private String label;
#Column(name = "VALUE")
private String value;
public long getAttr_id() {
return attr_id;
}
public void setAttr_id(long attr_id) {
this.attr_id = attr_id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
#ManyToOne
#JoinColumn(name = "ATTR_ID", referencedColumnName = "ID", insertable
= false, updatable = false)
private ProductAttr productAttr;
public ProductAttr getProductAttr() {
return productAttr;
}
public void setProductAttr(ProductAttr productAttr) {
this.productAttr = productAttr;
}
public ProductAttrValue() {
super();
// TODO Auto-generated constructor stub
}
}
Your indentation suggests a wrong mindset. These stream() operation are not on the same level. You have a nested operation:
listProducts.stream().forEachOrdered(listproducts ->
listproducts.getProductAttr().stream().forEachOrdered(attr ->
attr.getProductAttrValue().stream()
.filter(av -> av.getLabel().equalsIgnoreCase("source"))
/*.stream()*/.forEachOrdered(av -> System.out.println(av.getValue()))
)
);
(I changed the misleading name attrlabel and attrval to av, as these aren’t labels or values; you’re invoking .getLabel() and .getValue() subsequently on these variables, so I used av for “ProductAttrValue”)
The filter operation is the only operation that is not nesting, as it is an intermediate operation chained to the stream and the terminal operation just has to be chained to the resulting stream. There is no stream() invocation necessary at that place (the one marked with /*.stream()*/).
That said, you should avoid such nested operation.
You can use
listProducts.stream()
.flatMap(listproducts -> listproducts.getProductAttr().stream())
.flatMap(attr -> attr.getProductAttrValue().stream())
.filter(av -> av.getLabel().equalsIgnoreCase("source"))
.forEachOrdered(av -> System.out.println(av.getValue()));
instead.
All stream methods return another stream. To convert back to a list you need to use a Collector:
<your stream>.collect(Collectors.toList());

Spring data repositories - performance issue

I'm using Spring , JPArepostories and hibernate, to save some entities to database.
My entities :
Users:
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
#Column(name = "CARDID",unique=true)
private String cardId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name ="SUPPLIERUSERID", nullable = true)
#JsonIgnore
private SupplierUser supplierUser;
#Column(name = "NAME")
private String name;
#Column(name = "SURENAME")
private String sureName;
#Column(name = "ACTIVE")
private Boolean active;
#Column(name = "SMS")
private String sms;
#Column(name = "EMAIL")
private String email;
#OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Box> boxList = new ArrayList<Box>();
#OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Notification> notificationList = new ArrayList<Notification>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public SupplierUser getSupplierUser() {
return supplierUser;
}
public void setSupplierUser(SupplierUser supplierUser) {
this.supplierUser = supplierUser;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSureName() {
return sureName;
}
public void setSureName(String sureName) {
this.sureName = sureName;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public String getSms() {
return sms;
}
public void setSms(String sms) {
this.sms = sms;
}
public List<Box> getBoxList() {
return boxList;
}
public void setBoxList(List<Box> boxList) {
this.boxList = boxList;
}
public List<Notification> getNotificationList() {
return notificationList;
}
public void setNotificationList(List<Notification> notificationList) {
this.notificationList = notificationList;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Users have boxes:
#Entity
#Table(name = "boxes")
public class Box {
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name ="USERID", nullable = true)
#JsonIgnore
private User user;
#Column(name = "BOXNUMBER",unique=true)
private int boxNumber;
#Column(name = "MODBUSADDRESS")
private int modbusAddress;
#Column(name = "MODBUSREGISTER")
private int modbusRegister;
#Column(name = "STATE")
private String state;
#OneToMany(mappedBy = "box", fetch =FetchType.EAGER,cascade = CascadeType.ALL)
private List<Transaction> transactionsList = new ArrayList<Transaction>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getModbusAddress() {
return modbusAddress;
}
public void setModbusAddress(int modbusAddress) {
this.modbusAddress = modbusAddress;
}
public int getModbusRegister() {
return modbusRegister;
}
public void setModbusRegister(int modbusRegister) {
this.modbusRegister = modbusRegister;
}
public List<Transaction> getTransactionsList() {
return transactionsList;
}
public void setTransactionsList(List<Transaction> transactionsList) {
this.transactionsList = transactionsList;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getBoxNumber() {
return boxNumber;
}
public void setBoxNumber(int boxNumber) {
this.boxNumber = boxNumber;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Boxes have transactions:
#Entity
#Table(name = "transactions")
public class Transaction {
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name ="BOXID", nullable = true)
#JsonIgnore
private Box box;
#Column(name = "TYPE")
private String type;
#Column(name = "SUPPLIERUSERCARDID")
private String supplierUserCardId;
#Column(name = "DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#OneToMany(mappedBy = "transaction", fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private List<Notification> notificationsList = new ArrayList<Notification>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Box getBox() {
return box;
}
public void setBox(Box box) {
this.box = box;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getSupplierUserCardId() {
return supplierUserCardId;
}
public void setSupplierUserCardId(String supplierUserCardId) {
this.supplierUserCardId = supplierUserCardId;
}
public List<Notification> getNotificationsList() {
return notificationsList;
}
public void setNotificationsList(List<Notification> notificationsList) {
this.notificationsList = notificationsList;
}
}
And transaction have notifications (notification refer as well to user):
#Entity
#Table(name = "notifications")
public class Notification {
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name ="TRANSACTIONID", nullable = true)
#JsonIgnore
private Transaction transaction;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name ="USERID", nullable = true)
#JsonIgnore
private User user;
#Column(name = "TYPE")
private String type;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CREATED")
private Date created;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "SENDED")
private Date sended;
#Column(name = "RETRIES")
private Long retries;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getSended() {
return sended;
}
public void setSended(Date sended) {
this.sended = sended;
}
public Long getRetries() {
return retries;
}
public void setRetries(Long retries) {
this.retries = retries;
}
public Transaction getTransaction() {
return transaction;
}
public void setTransaction(Transaction transaction) {
this.transaction = transaction;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
And my question is - what I'm doing wrong, because following method for list with 150 boxes inside takes about 20 seconds to finish.
public void changeBoxOwners(ArrayList<Box> boxList){
String id = theSoftwareCore.getSupplierUser().getCardId();
ArrayList<Box> boxToSave = new ArrayList<Box>();
for (Box box : boxList){
Box existingBox = theSoftwareCore.boxServiceImp.findByBoxNumber(box.getBoxNumber());
existingBox.setState("full");
User user = theSoftwareCore.userServiceImp.findOneByCardId(box.getUser().getCardId());
//deleting not sent notifications
for (Transaction trans : existingBox.getTransactionsList()){
for (Notification notif: trans.getNotificationsList()){
if (notif.getSended()==null){
notif.setSended(new Date(0));
}
}
}
Transaction transaction = new Transaction();
transaction.setType("in");
transaction.setSupplierUserCardId(id);
transaction.setDate(new Date());
transaction.setBox(existingBox);
Notification notification = new Notification();
notification.setCreated(new Date());
notification.setType("smsTakeYourStaff");
notification.setTransaction(transaction);
notification.setUser(user);
existingBox.setUser(user);
transaction.getNotificationsList().add(notification);
existingBox.getTransactionsList().add(transaction);
boxToSave.add(existingBox);
}
System.out.println("Start saving" + new Date());
theSoftwareCore.boxServiceImp.saveAll(boxToSave);
System.out.println("End " + new Date());
}
Thanks for your time in advance.

Resources