JPA doesn't auto- create tables with OneToMany and ManyToOne relationships - java

I try to create tables automatically with Spring Boot Jpa but it doesn't work, it doesn't execute any sql queries. I suspect it's due to the OneToMany or ManytoOne relationships. I looked up the website but failed to find a question with a similar problem. Spring doesn't execute any queries and create any tables.
Users can create many posts and each post has many comments etc.
Here are my entities:
User.java
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long userId;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Topic> topics = new ArrayList<>();
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts = new ArrayList<>();
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
Post.java
#Entity
#Table
public class Post {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long postId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "userId", referencedColumnName = "userId")
private User user;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id", referencedColumnName = "id")
private Topic topic;
#OneToMany(mappedBy = "post", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
Comment.java
#Entity
#Table
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "postId", referencedColumnName = "postId")
private Post post;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "userId", referencedColumnName = "userId")
private User user;
Topic.java
#Entity
#Table
public class Topic {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "topic", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts = new ArrayList<>();
#NotNull
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "userId", referencedColumnName = "userId")
private User user;
application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/portfolio2?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=ecommerceapp
spring.datasource.password=ecommerceapp
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-
auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
application start logs:
2020-10-17 18:56:17.694 INFO 2196 --- [ main] c.j.s.SpringPortfolioApplication : Starting SpringPortfolioApplication on Laptop with PID 2196 (C:\Users\UserOld.Laptop\IdeaProjects\spring-portfolio\target\classes started by UserOld in C:\Users\UserOld.Laptop\IdeaProjects\spring-portfolio)
2020-10-17 18:56:17.694 INFO 2196 --- [ main] c.j.s.SpringPortfolioApplication : No active profile set, falling back to default profiles: default
2020-10-17 18:56:18.147 WARN 2196 --- [kground-preinit] o.s.h.c.j.Jackson2ObjectMapperBuilder : For Jackson Kotlin classes support please add "com.fasterxml.jackson.module:jackson-module-kotlin" to the classpath
2020-10-17 18:56:18.553 INFO 2196 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.
2020-10-17 18:56:18.585 INFO 2196 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23ms. Found 0 JPA repository interfaces.
2020-10-17 18:56:19.303 INFO 2196 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-10-17 18:56:19.319 INFO 2196 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-10-17 18:56:19.319 INFO 2196 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]
2020-10-17 18:56:19.491 INFO 2196 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-10-17 18:56:19.491 INFO 2196 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1735 ms
2020-10-17 18:56:19.663 INFO 2196 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-10-17 18:56:19.699 INFO 2196 --- [ task-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-10-17 18:56:19.730 WARN 2196 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-10-17 18:56:19.730 INFO 2196 --- [ task-1] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.21.Final
2020-10-17 18:56:19.855 INFO 2196 --- [ task-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-10-17 18:56:19.949 INFO 2196 --- [ task-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-10-17 18:56:20.011 WARN 2196 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
2020-10-17 18:56:20.105 INFO 2196 --- [ task-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2020-10-17 18:56:20.121 INFO 2196 --- [ task-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2020-10-17 18:56:20.168 INFO 2196 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-10-17 18:56:20.168 INFO 2196 --- [ main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
2020-10-17 18:56:20.168 INFO 2196 --- [ main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-10-17 18:56:20.183 INFO 2196 --- [ main] c.j.s.SpringPortfolioApplication : Started SpringPortfolioApplication in 2.932 seconds (JVM running for 3.878)
What is my mistake? Thank you!

The reason was that dll-auto doesn't work without Jpa or Crud repository so i created them and it started to work.

Related

Issue retrieving an integer using restTemplate

I am currently learning spring cloud microservices and I follow a really simple example.
So I have 2 services 1 for currency exchange and 1 for currency conversion. those two services talk to each other using 'resttemplate', however, when I try to get an object from currency exchange service I get all fields apart from the integer one, which return 0.
Beans:
CurrencyExchange:
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class CurrencyExchange {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "currency_from")
private String from;
#Column(name = "currency_to")
private String to;
private int convertionMultiple;
private String environment;
CurrencyConversion:
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class CurrencyConversion {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "from_currency")
private String from;
#Column(name = "to_currency")
private String to;
private int conversionMultiple;
private int quantity;
private int totalCalculatedAmount;
private String environment;
}
Controllers:
CurrencyExchange Controller:
#RestController
#RequestMapping("/exchange")
public class exchangeCurrencyController {
#Autowired
private Environment environment;
#Autowired
private CurrencyExchangeService currencyExchangeService;
#GetMapping("/currency-exchange/from/{from}/to/{to}")
public CurrencyExchange exchangeCurrency(#PathVariable String from, #PathVariable String to) {
CurrencyExchange currencyExchange = currencyExchangeService.findByFromAndTo(from, to);
String port = environment.getProperty("local.server.port");
System.out.println(currencyExchange);
currencyExchange.setEnvironment(port);
return currencyExchange;
}
CurrencyConversion Controller:
#RestController
#RequestMapping("/conversion")
public class CurrencyConversionController {
#GetMapping("/currency-conversion/from/{from}/to/{to}/quantity/{quantity}")
public CurrencyConversion getCurrencyConversion(#PathVariable String from, #PathVariable String to, #PathVariable int quantity) {
HashMap<String, String> uriVariables = new HashMap<>();
uriVariables.put("from", from);
uriVariables.put("to", to);
ResponseEntity<CurrencyConversion> responseEntity = new RestTemplate().getForEntity("http://localhost:8000/exchange/currency-exchange/from/{from}/to/{to}", CurrencyConversion.class, uriVariables);
CurrencyConversion currencyConversion1 = responseEntity.getBody();
System.out.println(currencyConversion1);
return new CurrencyConversion(currencyConversion1.getId(), currencyConversion1.getFrom(), currencyConversion1.getTo(), currencyConversion1.getConversionMultiple(), quantity, currencyConversion1.getConversionMultiple(), currencyConversion1.getEnvironment());
}
}
I have 3 object in my data base.
id conversion_multiple environment currency_from currency_to
1 12 8000 AUS ILS
2 65 8000 USD ILS
3 424 8000 INR ILS
**Web debuging log:
ExchangeCurrency Class:
2021-12-16 21:39:00.550 DEBUG 6648 --- [nio-8000-exec-3] o.s.web.servlet.DispatcherServlet : GET "/exchange/currency-exchange/from/USD/to/ILS", parameters={}
2021-12-16 21:39:00.551 DEBUG 6648 --- [nio-8000-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.in28minutes.microservices.currencyexchangeservice.controllers.exchangeCurrencyController#exchangeCurrency(String, String)
2021-12-16 21:39:00.552 DEBUG 6648 --- [nio-8000-exec-3] org.hibernate.SQL : select currencyex0_.id as id1_0_, currencyex0_.conversion_multiple as conversi2_0_, currencyex0_.environment as environm3_0_, currencyex0_.currency_from as currency4_0_, currencyex0_.currency_to as currency5_0_ from currency_exchange currencyex0_ where currencyex0_.currency_from=? and currencyex0_.currency_to=?
2021-12-16 21:39:00.557 DEBUG 6648 --- [nio-8000-exec-3] org.hibernate.SQL : select currencyex0_.id as id1_0_, currencyex0_.conversion_multiple as conversi2_0_, currencyex0_.environment as environm3_0_, currencyex0_.currency_from as currency4_0_, currencyex0_.currency_to as currency5_0_ from currency_exchange currencyex0_ where currencyex0_.currency_from=? and currencyex0_.currency_to=?
PrintCurrencyExchange{id=2, from='USD', to='ILS', convertionMultiple=65, environment='8000'}
2021-12-16 21:39:00.561 DEBUG 6648 --- [nio-8000-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2021-12-16 21:39:00.562 DEBUG 6648 --- [nio-8000-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [CurrencyExchange{id=2, from='USD', to='ILS', convertionMultiple=65, environment='8000'}]
2021-12-16 21:39:00.564 DEBUG 6648 --- [nio-8000-exec-3] o.s.web.servlet.DispatcherServlet : Completed 200 OK
CurrencyConversion Class**
2021-12-16 21:37:39.776 DEBUG 10736 --- [nio-8100-exec-9] o.s.web.servlet.DispatcherServlet : GET "/conversion/currency-conversion-feign/from/USD/to/ILS/quantity/1123123", parameters={}
2021-12-16 21:37:39.777 DEBUG 10736 --- [nio-8100-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.in28minutes.microservices.currencyconversionservice.controllers.CurrencyConversionController#getCurrencyConversionFeign(String, String, int)
2021-12-16 21:37:39.795 DEBUG 10736 --- [nio-8100-exec-9] o.s.w.c.HttpMessageConverterExtractor : Reading to [com.in28minutes.microservices.currencyconversionservice.beans.CurrencyConversion]
CurrencyConversion(id=2, from=USD, to=ILS, conversionMultiple=0, quantity=0, totalCalculatedAmount=0, environment=8000)
2021-12-16 21:37:39.798 DEBUG 10736 --- [nio-8100-exec-9] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [application/json, application/*+json, application/json, application/*+json]
2021-12-16 21:37:39.798 DEBUG 10736 --- [nio-8100-exec-9] m.m.a.RequestResponseBodyMethodProcessor : Writing [CurrencyConversion(id=2, from=USD, to=ILS, conversionMultiple=0, quantity=1123123, totalCalculatedAm (truncated)...]
2021-12-16 21:37:39.800 DEBUG 10736 --- [nio-8100-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK
when I print to console the response. I get
CurrencyConversion(id=2, from=USD, to=ILS, conversionMultiple=0, quantity=0, totalCalculatedAmount=0, environment=8000)
which shows String returning but int showing 0.
help me understand this.
THANKS
you need to add a #Column configuration:
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class CurrencyExchange {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "currency_from")
private String from;
#Column(name = "currency_to")
private String to;
#Column(name = "conversion_multiple")
private int convertionMultiple;
private String environment;
}
otherwise Spring does not know which column to load the data from as the field name does not match your column name.

Hibernate deleting parent objects when trying to delete child

I am having self join table CATEGORY. When I am trying to delete child entries, my parent entries ae also getting deleted. I am using Oracle 19.3 Db.
Eg.
[
{
"id": 5,
"name": "parent",
"display_name": "parent",
"parent_id": 0
},
{
"id": 6,
"name": "child",
"display_name": "child",
"parent_id": 5
}
]
Upon deleting entry with 6, entry of id 5 is also getting deleted.
My Class
#Entity
#Table(name="CATEGORY")
public class Category implements Serializable {
#Id
#Column(name = "id", nullable = false, updatable = false, unique = true)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name", nullable = false, updatable = true, unique = false)
private String name;
#Column(name = "display_name", nullable = false, updatable = true, unique = false)
private String displayName;
#NotFound(action = NotFoundAction.IGNORE)
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="parent_id")
private Category parent;
//Setter and Getters and Constructors
Logs from Spring boot are as follow
2021-04-30 14:50:57.345 DEBUG 2588 --- [nio-8080-exec-3] org.hibernate.SQL :
delete
from
category
where
id=?
2021-04-30 14:50:57.345 TRACE 2588 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [4]
2021-04-30 14:50:57.403 DEBUG 2588 --- [nio-8080-exec-3] org.hibernate.SQL :
delete
from
category
where
id=?
2021-04-30 14:50:57.405 TRACE 2588 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [3]
2021-04-30 14:50:57.518 INFO 2588 --- [nio-8080-exec-3] c.e.c.service.impl.CategoryServiceImpl : Course category deleted with chain
You can try to look into your #Cascade annotation with hibernate. It cascades operation between related entities and it looks you are cascading all actions.
cascade={CascadeType.ALL}, which all includes CascadeType.REMOVE.
Refer: https://www.educba.com/cascade-in-hibernate/

I have a problem when trying to run a spring boot application

So i have been working on a spring boot application for a school project and i cant run it because when i try to save in a repository i get the following errors. I have tried many things like changing the relation types ,adding cascades but nothing seems to work. Below is the code for 2 classes and main and also the errors
package com.site.anime.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Fetch;
import javax.persistence.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Data
public class Show {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String image;
private Integer no_episodes;
private String description;
private Double overall_score;
#ManyToMany
private List<Caracter> caracters;
#OneToMany
private List<Review> reviews;
#ManyToMany
private List<Category> categories;
}
package com.site.anime.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.List;
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Data
public class Caracter {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String image;
private String description;
#ManyToMany
private List<Show> shows;
}
package com.site.anime;
import com.site.anime.model.*;
import com.site.anime.repository.*;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
#EnableJpaRepositories
#SpringBootApplication
public class AnimeApplication {
public static void main(String[] args) {
SpringApplication.run(AnimeApplication.class, args);
}
#Bean
CommandLineRunner init(RepositoryShow repositoryShow, RepositoryCategory repositoryCategory,
RepositoryCaracter repositoryCaracter, RepositoryUser repositoryUser,
RepositorySuperUser repositorySuperUser){
return args -> {
List<Show> shows=new LinkedList<>();
Caracter caracter=new Caracter(null,"rusu","","",null);
List<Caracter> caracters=new LinkedList<>();
caracters.add(caracter);
Profile profile=new Profile();
Utilizator user=new Utilizator(null,"","","",profile,null);
//Review review=new Review(null,user,"",0);
Review review=new Review(null,null,"",0);
List<Review> reviews=new LinkedList<>();
reviews.add(review);
user.setReviews(reviews);
Show show=new Show(null,"ReZero Season 1","",25,"",0.0,null,reviews,null);
shows.add(show);
caracter.setShows(shows);
show.setCaracters(caracters);
//
//repositoryShow.save(show);
repositoryCaracter.save(caracter);
//repositoryUser.save(user);
};
}
}
and the errors
2021-03-11 14:11:02.765 INFO 10248 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-03-11 14:11:02.771 INFO 10248 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-03-11 14:11:03.007 WARN 10248 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-03-11 14:11:03.065 INFO 10248 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-03-11 14:11:03.193 INFO 10248 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-03-11 14:11:03.198 INFO 10248 --- [ main] com.site.anime.AnimeApplication : Started AnimeApplication in 2.922 seconds (JVM running for 3.566)
2021-03-11 14:11:03.245 WARN 10248 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1064, SQLState: 42000
2021-03-11 14:11:03.245 ERROR 10248 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'show (description, image, name, no_episodes, overall_score, id) values ('', '', ' at line 1
2021-03-11 14:11:03.252 INFO 10248 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-03-11 14:11:03.263 ERROR 10248 --- [ main] o.s.boot.SpringApplication : Application run failed
``
SHOW is a keyword for MySql (as well as NAME and DESCRIPTION), so you should use SQL quoted identifier, like below:
#Entity
#Table(name = "`show`")
public class Show {
// ...
#Column(name = "`name`")
private String name;
#Column(name = "`description`")
private String description;
}
I solved the problem
For anyone wondering ,one of my classes was called Show,and sql has a reserved word called show

Hibernate and postgresql. Errors while exporting schema

I'm getting around 10 errors when I start my Spring Boot app using Hibernate and postgresql. How can I fix them? WHat's the problem?
Here are my entities:
Customer.java
#Entity
#Access(AccessType.FIELD) // so I can avoid using setters for fields that won't change
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long customerId;
#Embedded
private FirstName firstName;
#Embedded
private LastName lastName;
#Embedded
private PhoneNumber phoneNumber;
#ManyToOne
#JoinColumn(name = "ADDRESS_ID")
private Address address;
#OneToOne
#JoinColumn(name = "USER_ID")
private User user;
// jpa requirement
public Customer() {
}
public Customer(FirstName firstName, LastName lastName,
PhoneNumber phoneNumber, Address address, User user) {
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.address = address;
this.user = user;
}
public Long getCustomerId() {
return customerId;
}
public FirstName getFirstName() {
return firstName;
}
public LastName getLastName() {
return lastName;
}
public PhoneNumber getPhoneNumber() {
return phoneNumber;
}
// setter for phone number is needed because customer can change his phone number
public void setPhoneNumber(PhoneNumber phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Address getAddress() {
return address;
}
// setter for address is needed because customer can change his address
public void setAddress(Address address) {
this.address = address;
}
public User getUser() {
return user;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Customer customer = (Customer) o;
if (firstName != null ? !firstName.equals(customer.firstName) : customer.firstName != null) {
return false;
}
if (lastName != null ? !lastName.equals(customer.lastName) : customer.lastName != null) {
return false;
}
return user != null ? user.equals(customer.user) : customer.user == null;
}
#Override
public int hashCode() {
int result = firstName != null ? firstName.hashCode() : 0;
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (user != null ? user.hashCode() : 0);
return result;
}
#Override
public String toString() {
return "Customer{" +
"firstName=" + firstName +
", lastName=" + lastName +
", phoneNumber=" + phoneNumber +
'}';
}
}
User.java
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
#Embedded
private EmailAddress emailAddress;
#Embedded
private Password password;
#OneToOne
#JoinColumn(name = "CUSTOMER_ID")
private Customer customer;
#Column
#Enumerated(EnumType.STRING)
private UserRole userRole;
// jpa requirement
public User() {
}
public User(EmailAddress emailAddress, Password password) {
this.emailAddress = emailAddress;
this.password = password;
this.userRole = UserRole.USER; // on creation everyone is just a user
}
public Long getUserId() {
return userId;
}
public EmailAddress getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(EmailAddress emailAddress) {
this.emailAddress = emailAddress;
}
public Password getPassword() {
return password;
}
public void setPassword(Password password) {
this.password = password;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public UserRole getUserRole() {
return userRole;
}
public void setUserRole(UserRole userRole) {
this.userRole = userRole;
}
}
And Book.java:
#Entity
#Access(AccessType.FIELD) // so I can avoid using setters for fields that won't change
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long bookId;
#Embedded
private Isbn isbn;
#Embedded
private Title title;
#Embedded
private Author author;
#Embedded
private Genre genre;
private Year publicationYear;
private BigDecimal price;
// jpa requirement
public Book() {
}
public Book(Isbn isbn, Title title, Author author, Genre genre, Year publicationYear,
BigDecimal price) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.genre = genre;
this.publicationYear = publicationYear;
this.price = price;
}
public Long getBookId() {
return bookId;
}
public Isbn getIsbn() {
return isbn;
}
public Title getTitle() {
return title;
}
public Author getAuthor() {
return author;
}
public Genre getGenre() {
return genre;
}
public BigDecimal getPrice() {
return price;
}
public Year getPublicationYear() {
return publicationYear;
}
// setter for price is needed because price of the book can change (discounts and so on)
public void setPrice(BigDecimal price) {
this.price = price;
}
}
My application.properties for postgresql settings:
spring.datasource.url= jdbc:postgresql://localhost:5432/bookrest
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=create-drop
And here is the stack trace for hibernate part (ommitted all the controoller mapping):
2017-02-27 11:03:05.481 INFO 6563 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2017-02-27 11:03:05.555 INFO 6563 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate Core {5.0.11.Final}
2017-02-27 11:03:05.556 INFO 6563 --- [ restartedMain] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-02-27 11:03:05.558 INFO 6563 --- [ restartedMain] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-02-27 11:03:05.609 INFO 6563 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-02-27 11:03:05.819 INFO 6563 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2017-02-27 11:03:05.997 INFO 6563 --- [ restartedMain] o.h.e.j.e.i.LobCreatorBuilderImpl : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
2017-02-27 11:03:05.999 INFO 6563 --- [ restartedMain] org.hibernate.type.BasicTypeRegistry : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType#c866efb
2017-02-27 11:03:06.228 WARN 6563 --- [ restartedMain] org.hibernate.orm.deprecation : HHH90000014: Found use of deprecated [org.hibernate.id.SequenceGenerator] sequence-based id generator; use org.hibernate.id.enhanced.SequenceStyleGenerator instead. See Hibernate Domain Model Mapping Guide for details.
2017-02-27 11:03:06.580 INFO 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-27 11:03:06.584 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table customer drop constraint FKglkhkmh2vyn790ijs6hiqqpi
2017-02-27 11:03:06.584 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: relation "customer" does not exist
2017-02-27 11:03:06.584 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table customer drop constraint FKidmyb2vdwmk3o502u0rg8g32h
2017-02-27 11:03:06.585 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: relation "customer" does not exist
2017-02-27 11:03:06.585 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table user drop constraint FK2q989f4c89rv2b9xvtomfc0fs
2017-02-27 11:03:06.586 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "user"
Position: 13
2017-02-27 11:03:06.587 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: drop table if exists user cascade
2017-02-27 11:03:06.587 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "user"
Position: 22
2017-02-27 11:03:06.588 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: drop sequence hibernate_sequence
2017-02-27 11:03:06.588 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: sequence "hibernate_sequence" does not exist
2017-02-27 11:03:06.607 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: create table user (user_id bigserial not null, email_address varchar(255), password varchar(255), user_role varchar(255), customer_customer_id int8, primary key (user_id))
2017-02-27 11:03:06.607 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "user"
Position: 14
2017-02-27 11:03:06.610 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table customer add constraint FKidmyb2vdwmk3o502u0rg8g32h foreign key (user_user_id) references user
2017-02-27 11:03:06.610 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "user"
Position: 103
2017-02-27 11:03:06.610 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table user add constraint FK2q989f4c89rv2b9xvtomfc0fs foreign key (customer_customer_id) references customer
2017-02-27 11:03:06.610 ERROR 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "user"
Position: 13
2017-02-27 11:03:06.611 INFO 6563 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-27 11:03:06.673 INFO 6563 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
EDIT 1:
After changing my User to AppUser (table name user is prohibited) I'm still getting few errors:
2017-02-27 11:45:44.253 INFO 9560 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate Core {5.0.11.Final}
2017-02-27 11:45:44.255 INFO 9560 --- [ restartedMain] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-02-27 11:45:44.256 INFO 9560 --- [ restartedMain] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-02-27 11:45:44.298 INFO 9560 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-02-27 11:45:44.621 INFO 9560 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2017-02-27 11:45:44.825 INFO 9560 --- [ restartedMain] o.h.e.j.e.i.LobCreatorBuilderImpl : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
2017-02-27 11:45:44.828 INFO 9560 --- [ restartedMain] org.hibernate.type.BasicTypeRegistry : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType#35c0ac4e
2017-02-27 11:45:45.370 INFO 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-27 11:45:45.373 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table app_user drop constraint FKf8cjd2mkc4tu1u5nhju0clae7
2017-02-27 11:45:45.374 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: relation "app_user" does not exist
2017-02-27 11:45:45.374 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table customer drop constraint FKglkhkmh2vyn790ijs6hiqqpi
2017-02-27 11:45:45.374 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: relation "customer" does not exist
2017-02-27 11:45:45.375 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table customer drop constraint FKslkyb5dphxe4c7au3hqx3la6m
2017-02-27 11:45:45.375 ERROR 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: relation "customer" does not exist
2017-02-27 11:45:45.408 INFO 9560 --- [ restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-27 11:45:45.467 INFO 9560 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
user is a reserved keyword in postgresql. I would suggest renaming your entity class to some other name, or just use hibernate annotations #Table to specify postgresql friendly table name, like this:
#Entity
#Table(name = "library_user")
public class User {...}
User is reserved word in most if not all of the databases. Use some other name for this purpose.
Words

How to update an item in one to many relationship

I am trying to update a one to many relationship but getting a
insert into sw_standard_standard (sw_standard_id, standard_id) values
(?, ?) [23505-192]]; nested exception is
org.hibernate.exception.ConstraintViolationException
Here is my code:
SwStandard
#Entity
public class SwStandard implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
#OneToOne
private DeviceType deviceType;
#ElementCollection
#OneToMany
private List<Image> standard;
#ElementCollection
#OneToMany
private List<Image> limited;
#ElementCollection
#OneToMany
private List<Image> exception;
public SwStandard() {}
public SwStandard(DeviceType deviceType, List<Image> standard, List<Image> limited, List<Image> exception) {
this.deviceType = deviceType;
this.standard = standard;
this.limited = limited;
this.exception = exception;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public DeviceType getDeviceType() {
return deviceType;
}
public void setDeviceType(DeviceType deviceType) {
this.deviceType = deviceType;
}
public List<Image> getStandard() {
return standard;
}
public void setStandard(List<Image> standard) {
this.standard = standard;
}
public List<Image> getLimited() {
return limited;
}
public void setLimited(List<Image> limited) {
this.limited = limited;
}
public List<Image> getException() {
return exception;
}
public void setException(List<Image> exception) {
this.exception = exception;
}
}
Image
#Entity
public class Image implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String name;
public Image() {}
public Image(String name) {
this.name = name;
}
public Image(Long id, String name) {
this.id = id;
this.name = name;
}
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;
}
}
Update code:
#RequestMapping(value = "/swstandard/update", method = RequestMethod.POST)
public SwStandard updateSwStandard(#RequestBody SwStandard request) {
return swService.save(request);
}
SwService:
#Autowired
private SwStandardRepository swService;
SwStandardRepository:
public interface SwStandardRepository extends CrudRepository<SwStandard, Long> {
SwStandard findByDeviceTypeId(Long id);
}
First I save a SwStandard with 1 standard item. Then I save want to replace the standard item with something else. When I do this it returns the error above.
Edit
Alan Hay help partially helped.
Now I cannot save the same image across a SwStandard for example here is a SwStandard I'll save:
{
"id": 1,
"deviceType": { "id": 1 },
"standard": [{"id": 1}],
"limited": [],
"exception": []
}
and here is another SwStandard I'll save which will fail with the error above:
{
"id": 2,
"deviceType": { "id": 2 },
"standard": [{"id": 1}],
"limited": [],
"exception": []
}
As you can see both SwStandards have the same standard item.
Here is the log output:
2016-11-08 16:19:12.060 INFO 15668 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-11-08 16:19:12.060 INFO 15668 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2016-11-08 16:19:12.092 INFO 15668 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 31 ms
2016-11-08 16:19:12.255 WARN 15668 --- [nio-8080-exec-1] org.hibernate.orm.deprecation : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead. See Hibernate Domain Model Mapping Guide for details.
2016-11-08 16:19:12.255 DEBUG 15668 --- [nio-8080-exec-1] org.hibernate.SQL : select sequence_next_hi_value from hibernate_sequences where sequence_name = 'sw_standard' for update
2016-11-08 16:19:12.256 DEBUG 15668 --- [nio-8080-exec-1] org.hibernate.SQL : insert into hibernate_sequences(sequence_name, sequence_next_hi_value) values('sw_standard', ?)
2016-11-08 16:19:12.258 DEBUG 15668 --- [nio-8080-exec-1] org.hibernate.SQL : update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'sw_standard'
2016-11-08 16:19:12.262 DEBUG 15668 --- [nio-8080-exec-1] org.hibernate.SQL : insert into sw_standard (device_type_id, id) values (?, ?)
2016-11-08 16:19:12.262 TRACE 15668 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2016-11-08 16:19:12.262 TRACE 15668 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1]
2016-11-08 16:19:12.264 DEBUG 15668 --- [nio-8080-exec-1] org.hibernate.SQL : insert into sw_standard_standard (sw_standard_id, standard_id) values (?, ?)
2016-11-08 16:19:12.270 TRACE 15668 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]
2016-11-08 16:19:12.271 TRACE 15668 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1]
2016-11-08 16:19:22.162 WARN 15668 --- [nio-8080-exec-2] org.hibernate.orm.deprecation : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead. See Hibernate Domain Model Mapping Guide for details.
2016-11-08 16:19:22.163 DEBUG 15668 --- [nio-8080-exec-2] org.hibernate.SQL : insert into sw_standard (device_type_id, id) values (?, ?)
2016-11-08 16:19:22.164 TRACE 15668 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2]
2016-11-08 16:19:22.164 TRACE 15668 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [2]
2016-11-08 16:19:22.165 DEBUG 15668 --- [nio-8080-exec-2] org.hibernate.SQL : insert into sw_standard_standard (sw_standard_id, standard_id) values (?, ?)
2016-11-08 16:19:22.166 TRACE 15668 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2]
2016-11-08 16:19:22.166 TRACE 15668 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [1]
2016-11-08 16:19:22.169 WARN 15668 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23505, SQLState: 23505
2016-11-08 16:19:22.169 ERROR 15668 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "UK_QM6PF2T2PB3DLYYLV44TQL40J_INDEX_2 ON PUBLIC.SW_STANDARD_STANDARD(STANDARD_ID) VALUES (1, 1)"; SQL statement:
insert into sw_standard_standard (sw_standard_id, standard_id) values (?, ?) [23505-192]
2016-11-08 16:19:22.172 INFO 15668 --- [nio-8080-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2016-11-08 16:19:22.194 ERROR 15668 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["UK_QM6PF2T2PB3DLYYLV44TQL40J_INDEX_2 ON PUBLIC.SW_STANDARD_STANDARD(STANDARD_ID) VALUES (1, 1)"; SQL statement:
insert into sw_standard_standard (sw_standard_id, standard_id) values (?, ?) [23505-192]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

Categories