Hibernate autogeneration of Id doesn't seem to be working - java

I have my entity called Post which has Id as a primary key.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "Id", unique = true, nullable = false)
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
In above code you may see GenerationType.IDENTITY which I would assume is responsible for generating a new ID in case of creation of a new Post.
However, when I make a HTTP POST with this JSON:
{"id":0,"title":"test","viewCount":0,"body":"test","tags":"","answerCount":0,"commentCount":0,"postTypeId":1,"favoriteCount":0,"creationDate":"Nov 25, 2015 11:43:22 AM","acceptedAnswerId":0,"lastEditorUserId":0,"score":0}
I am getting this error:
SEVERE: Servlet.service() for servlet [rest] in context with path [/StackExchange] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement] with root cause
java.sql.SQLException: Field 'Id' doesn't have a default value
I haven't set AI though, maybe that is the cause. But I am unable to alter the table. The data in the table are from SQL dumps and I can't alter it to set Id as AutoIncrement

Related

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptDataSourceInitializer'

I tried to compile very easy program with saving easy table with 3 users to http://localhost/phpmyadmin to empty database named ,,users'' but it still show me exceptions which you can see.
1 exception org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scriptDataSourceInitializer' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceInitializationConfiguration$SharedCredentialsDataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data.sql]: insert into user (name,surname,email,city) values ('Przemek','Mazurek','przemyslaw.mazurek#gmail.com','Warsaw'), ('Anna', 'Grodna','anna.grodna#gmail.com','Lublin'), ('Zosia','Gulina','zosia.gulina#gmail.com','Praga'); nested exception is java.sql.SQLSyntaxErrorException: Table 'users.user' doesn't exist
2 exception: Caused by: java.sql.SQLSyntaxErrorException: Table 'users.user' doesn't exist
3 exception: Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data.sql]: insert into user (name,surname,email,city) values ('Przemek','Mazurek','przemyslaw.mazurek#gmail.com','Warsaw'), ('Anna', 'Grodna','anna.grodna#gmail.com','Lublin'), ('Zosia','Gulina','zosia.gulina#gmail.com','Praga'); nested exception is java.sql.SQLSyntaxErrorException: Table 'users.user' doesn't exist
[applications.properties file][1]
[User and Entity class][2]
[data.sql file][3]
[User Repository][4]
[1]: https://i.stack.imgur.com/R8A5T.png
[2]: https://i.stack.imgur.com/29Yym.png
[3]: https://i.stack.imgur.com/u4aWt.png
[4]: https://i.stack.imgur.com/laAB3.png
I think that you are missing a table in your users database.
The issue is that you are trying to insert the data, into your table, which is not present in your database.
Try to execute this script and try again
CREATE TABLE user (
id int NOT NULL AUTO_INCREMENT,
name varchar(255),
surname varchar(255),
email varchar(255),
city varchar(255),
PRIMARY KEY (id)
);
Also don't forget to properly map your entity to your database
#Entity
#Getter #Setter #NoArgsConstructor
#Table(name="user")
public class User{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#Column(name="name")
private String name;
#Column(name="surname")
private String surname;
#Column(name="email")<-- this email is matching value of the field in the database
private String email;<-- this email is your entity field
#Column(name="city")
private String city ;

Duplicate entry '2' for key error in Spring jpa

I am working on a spring boot app where I am using JPA for all data transactions and I came across this error while using OneToMany relationship.
Here are both my models:
user.java
#Entity
public class user {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String role;
#ManyToOne(cascade=CascadeType.ALL)
private file f;
#JsonIgnore
#OneToMany(targetEntity=job.class,cascade=CascadeType.ALL)
private List<job> applied;
//getters ,setters and constuctors.
}
job.java
#Entity
public class job {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String role;
private String company;
private String salary;
private String description;
private String level;
private Date expiry;
private String skills;
private String location;
#JsonIgnore
#OneToMany(targetEntity=user.class,cascade=CascadeType.ALL)
private List<user> candidates;
//getters setters and constructor
}
here's the method that triggers the error:
public String applyToJob(Integer userId,Integer jobId)
{
job jobToApply= jobRepo.getOne(jobId);
user applier=userRepo.getById(userId);
List<job> jobs=applier.getApplied();
jobs.add(jobToApply);
applier.setApplied(jobs);
userRepo.save(applier);
List<user> candidates=jobToApply.getCandidates();
System.out.println(candidates);
candidates.add(userRepo.getOne(userId));
System.out.println(candidates);
jobToApply.setCandidates(candidates);
jobRepo.save(jobToApply);
return "Job Apply Success";
}
Now that I want to add data inside job's candidates field I get the below error:
2021-10-07 17:17:37.542 WARN 21696 --- [nio-8090-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1062, SQLState: 23000
2021-10-07 17:17:37.543 ERROR 21696 --- [nio-8090-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry '2' for key 'job_candidates.UK_q0o76ghxl59c5ip3qwatsxo3f'
2021-10-07 17:17:37.543 INFO 21696 --- [nio-8090-exec-4] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2021-10-07 17:17:37.564 ERROR 21696 --- [nio-8090-exec-4] 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 [job_candidates.UK_q0o76ghxl59c5ip3qwatsxo3f]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '2' for key 'job_candidates.UK_q0o76ghxl59c5ip3qwatsxo3f'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.26.jar:8.0.26]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java
Seems like you are adding a candidate to the job entity, which is already previously mapped to that particular job.
Please thoroughly check your entries in the DB and try to find out if there is any candidate that is being added multiple times to the same job, preferably with id as 2.
Let me know if you face any further difficulties!

Use entity's value in query with Hibernates #Formula annotation

Given the following db structure:
And having the following mapping for this structure:
#Entity
#Table(name = "a")
class A {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false, nullable = false)
private int aId;
#Column(name = "title")
private String title;
#Formula("(SELECT COUNT(*) FROM b WHERE b.a_id = aId)")
private Integer count;
}
My aim is to get the count of all references to A from B (where aId in the query is the value of the current entity).
But I get following Error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
java.sql.SQLException: Unknown column 'a0_.aId' in 'where clause'
As Simon mentioned you need to use the name of the column, not the attribute name. In your example above this would be:
#Formula("(SELECT COUNT(*) FROM b WHERE b.a_id = id)")
You have to use the name of the column not the attribute name:
#Formula("(SELECT COUNT(*) FROM b WHERE b.a_id = a_id)")

POST REST API with One-To-Many Mapping : Cannot be null error

I have two tables: tbl_services & tbl_sub_services. one service can have multiple sub-services. I am developing REST API using spring boot and trying to post data in services & subservices table. I can post data in services table but getting issue while posting in sub-services table. It's one-to-Many bidirectional Mapping.
Here is an exception which I am getting in postman.
{
"timestamp": "2019-06-09T04:10:22.002+0000",
"status": 500,
"error": "Internal Server Error",
"message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
"trace": "org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement\n\tat
.
.
.
.
'tbl_services_id' cannot be null\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)\n\tat com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:955)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1094)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1042)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1345)\n\tat com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1027)\n\tat com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)\n\tat com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)\n\tat org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)\n\t... 94 more\n",
"path": "/api/subservices"
Here is structure of both tables :
Entity Classes :
Services.class
#Entity
#Table(name="tbl_services")
public class Service {
// define fields
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="tbl_services_id")
private int id;
#Column(name="service_name")
private String serviceName;
#Column(name="service_desc")
private String serviceDesc;
#Column(name="service_image")
private String serviceImage;
#OneToMany(mappedBy="service",
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
private List<SubService> subServices;
public List<SubService> getSubServices() {
return subServices;
}
public void setSubServices(List<SubService> subServices) {
this.subServices = subServices;
}
}
SubService.class
#Entity
#Table(name="tbl_sub_services")
public class SubService {
// define fields
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="tbl_sub_services_id")
private int id;
#ManyToOne(
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
#JoinColumn(name="tbl_services_id")
#JsonIgnore
private Service service;
public Service getService() {
return service;
}
#Column(name="sub_service_name")
private String subServiceName;
#Column(name="sub_service_desc")
private String subServiceDesc;
#Column(name="sub_service_image")
private String subServiceImage;
I am trying to post data from postman then I am getting an exception. Here is data which I am posting from postman.
Here is SubServicesHibernateDAOImpl.class
#Override
public void saveSubService(SubService theSubService) {
// get the current hibernate session
Session currentSession = entityManager.unwrap(Session.class);
System.out.println("SubService object : "+theSubService);
currentSession.saveOrUpdate(theSubService);
}
EDIT :
Here is json payload I am receiving in saveSubService method :
[id=0, service=null, subServiceName=GST, subServiceDesc=GST is a subservice which currently having , subServiceImage=path-to-image]
You get:
could not execute statement; SQL [n/a]; constraint [null]
I see that you are passing the service in the request but I do not see you load it before the save of SubService:
#Override
public void saveSubService(SubService theSubService) {
Session currentSession = entityManager.unwrap(Session.class);
Service loadedService = currentSession.load(Service.class
, theSubService.getService.getId();
theSubService.setService(loadedService);
currentSession.saveOrUpdate(theSubService);
}
or try to simply merge as you have proper cascading already in place:
#Override
public void saveSubService(SubService theSubService) {
// get the current hibernate session
Session currentSession = entityManager.unwrap(Session.class);
System.out.println("SubService object : "+theSubService);
currentSession.merge(theSubService);
}
Also, I am not sure why you need to unwrap the session. EntityManager and its interface would be sufficient in this case.

Hibernate Select certain columns that are entity objects

I am trying to use Spring Boot (and obviously I am a newbie) along with Hibernate.
#Entity
public class UserRole {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long userRoleId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="user_id")
private User user;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="role_id")
private Role role;
}
I am trying to retrieve only the List of User Objects without having to rely on a UserRole object List to take them.
I tried the following into my UserRoleRepository
#Query("select u.user from user_role u where u.role = :role")
public ArrayList<User> findByRoleQ(Role role);
When i tried the above query I got a missmatch mapping error When i tried to run it as follows
2018-01-27 18:14:12.299 WARN 10720 --- [ main]
ationConfigEmbeddedWebApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'afdempUisuxAdminApplication':
Unsatisfied dependency expressed through field 'userRoleService';
nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userRoleServiceImpl': Unsatisfied
dependency expressed through field 'userRoleRepository'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'userRoleRepository': Invocation of init
method failed; nested exception is java.lang.IllegalArgumentException:
Validation failed for query for method public abstract
java.util.ArrayList
org.afdemp.uisux.repository.UserRoleRepository.findByRoleQ(org.afdemp.uisux.domain.security.Role)!
What am I doing wrong and is there a way to make it return only the User column (thus User List)?

Categories