UserDO.java
#Entity
#Table(name = "UserDO")
public class UserDO {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
private boolean successfullyLinked;
private UserInformation userInformation;
}
UserInformation.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "address", "country_code", "currency_code", "email_address", "name", "phone" })
public class UserInformation {
#JsonProperty("address")
#Valid
private Address address;
#JsonProperty("country_code")
#NotNull
private String countryCode;
#JsonProperty("currency_code")
#Size(min = 3, max = 3)
private String currencyCode;
#JsonProperty("email_address")
#NotNull
private String emailAddress;
#JsonProperty("name")
#Valid
#NotNull
private Name name;
#JsonProperty("phone")
#Valid
private Phone phone;
}
I am trying to save the UserInformation POJO as a part of the UserDO in Hibernate. However upon running this as part of a Spring Boot Application, I get an error. The following is the stack trace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.MappingException: Could not determine type for: com.paypal.marketplaces.vaas.api.models.UserInformation, at table: Tracking, for columns: [org.hibernate.mapping.Column(userInformation)]
Note: The UserInformation POJO is quite complex, with other objects inside it and objects inside those objects (and so on). Any solution not requiring explicit mapping of the UserInformation POJO to colums of the UserDO table would be preferable.
Any help would be highly appreciated!
Persistence provider is not aware of that class, neither what to do with it.
I would suggest making it Embeddable and optionally specifying column names:
import javax.persistence.Embeddalbe;
import javax.persistence.Column;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "address", "country_code", "currency_code", "email_address", "name", "phone" })
#Embeddable
public class UserInformation {
#JsonProperty("country_code")
#NotNull
#Column(name = "COUNTRY_CODE")
private String countryCode;
You would have to repeat the process for every nested class.
And finally to annotate the userInformation with:
#Embedded
private UserInformation userInformation;
Related
i have a jdbcTemplate.query method with query bit complex with multiple left joins, so its difficult for me to implement interface based repository methods.
I am using a MySQL db from AWS RDS.
when the query is executing spring boot jpa automatically converting table name to upper case and it throws error as: table not found.
exception is:
with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [SELECT DISTINCT test_desc FROM test_name_table]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TEST_NAME_TABLE" not found; SQL statement:
SELECT DISTINCT test_desc FROM test_name_table [42102-200]] with root cause
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TEST_NAME_TABLE" not found; SQL statement:
SELECT DISTINCT test_desc FROM test_name_table [42102-200]
here are the solutions i have tried:
from application.properties:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.DefaultNamingStrategy
database url:
spring.datasource.dataSourceProperties.serverName=test-instance.us-east-1.rds.amazonaws.com;DATABASE_TO_UPPER=FALSE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;
as you see above sql query, i have even put the table name inside backtick. but no luck.
I tried to rename the table name in MySQL to TEST_NAME_TABLE, but still no luck.
any recommended fix for this?
its a good practice use #Table(name = "table_name") for a model and #Column(name = "column_name") annotation for every column in your Model.java
and use #Query("some query in SQL") for every query you use in ModelRepository.java
example:
#Entity
#Table
public class Employee implements Serializable {
#Id
#Column(name = "emp_id")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#Column(name = "jobTitle")
private String jobTitle;
#Column(name = "phone")
private String phone;
#Column(name = "imagUrl")
private String imageUrl;
#Column(name = "employeeCode")
private String employeeCode;
}
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
#Query("SELECT s FROM Employee s WHERE s.email = ?1")
Optional<Employee> findEmployeeByEmail(String email);
}
I have an Entity like this:
#Entity
#Data
public class Cat {
#Id
private String catId;
private String catName;
private List<String> favFoods;
}
When I start my Spring boot, it shows this error:
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List
I drop the table Cat in DB before starting the app
My yml setting is:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/localtest
username: catuser
password:
jpa:
show-sql: false
hibernate:
ddl-auto: create
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true
If I comment out the field of List, everything works fine.
Is there any annotation that I need to add to solve this problem?
Thank you
You can also use the following code snippet
#ElementCollection
#CollectionTable(name = "my_list", joinColumns = #JoinColumn(name =
"id"))
#Column(name = "list")
List<String> favFoods;
See here
You have to tell Hibernate how to map the list by annotating you class with #TypeDef(name = "list-array",typeClass = ListArrayType.class) and annotating the list with #Type(type = "list-array") i.e.:
#Entity
#Data
#TypeDef(
name = "list-array",
typeClass = ListArrayType.class
)
public class Cat {
#Id
private String catId;
private String catName;
#Type(type = "list-array")
private List<String> favFoods;
}
I am trying to fetch all rows with my foreign key attribute but I am getting error
Doctor class
#Entity
#Table(name = "doctors")
public class Doctor implements Serializable {
#Column(name = "doctor_id")
private #Id #GeneratedValue(strategy = GenerationType.IDENTITY) int doctorid;
private #NotBlank String doctor_name;
private #NotBlank String speciality;
Appointment class
#Entity
#Table(name = "appointments")
public class Appointment implements Serializable {
#Id
#GeneratedValue
private #NotBlank int App_id;
private #NotBlank String date;
private #NotBlank String time;
#ManyToOne(targetEntity = Doctor.class,cascade = {CascadeType.ALL})
#JsonBackReference("doctors")
#JoinColumn(name = "doctor_id")
private Doctor doctor_id;
Controller
#GetMapping("/appointmentsbydoctor")
public ResponseEntity<Object> doctorsappointment(#Valid #RequestParam(name = "doctor_id") int id) {
return new ResponseEntity<>(appointmentService.appointment(id), HttpStatus.OK);
}
Service class
public List<Appointment> appointment(int id){
List<Appointment> a= appointmentRepository.findAllByDoc(id);
return a;
}
Repository
public interface AppointmentRepository extends JpaRepository<Appointment, Integer> {
#Query(name="select * from Appointment a where a.doctor_id.doctorid=:id",nativeQuery = true)
List<Appointment> findAllByDoc(int id);
I am getting this error
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appointmentController' defined in file [D:\courses\Inellij\appointment\target\classes\com\doctor\appointment\controller\AppointmentController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appointmentServiceImpl': Unsatisfied dependency expressed through field 'appointmentRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appointmentRepository' defined in com.doctor.appointment.repository.AppointmentRepository defined in #EnableJpaRepositories declared on AppointmentApplication: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.doctor.appointment.repository.AppointmentRepository.findAllByDoc(int)! Reason: Failed to create query for method public abstract java.util.List com.doctor.appointment.repository.AppointmentRepository.findAllByDoc(int)! No property doc found for type Appointment!; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.doctor.appointment.repository.AppointmentRepository.findAllByDoc(int)! No property doc found for type Appointment!
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.9.jar:5.3.9]
What should I do, I looked for a lot of solution but nothing works. How should I proceed further?
By changing my query value= to name=, I was able to solve the problem. The latter is used to reference a named query
I am using an interface LoanInterface.java to display values upon request. My problem is I am encountering this error:
Invalid property 'accountNumber' of bean class [com.meteor.coral.portfolio.modules.loanaccount.domain.Loan$HibernateProxy$Vm2InzHB]:
Getter for property 'accountNumber' threw exception; nested exception is java.lang.reflect.InvocationTargetException;
nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid property 'accountNumber' of bean class
[com.meteor.coral.portfolio.modules.loanaccount.domain.Loan$HibernateProxy$Vm2InzHB]: Getter for property 'accountNumber' threw exception;
nested exception is java.lang.reflect.InvocationTargetException
(through reference chain: org.springframework.data.domain.PageImpl["content"]
->java.util.Collections$UnmodifiableRandomAccessList[0]->com.sun.proxy.$Proxy394["loanId"]->com.sun.proxy.$Proxy395["accountNumber"])]
This is my LoanInterface.java
#JsonPropertyOrder({
"id",
"accountNumber"
})
public interface LoanInterface {
public Long getId();
public String getAccountNumber();
}
This is the model, Loan.java, where I want to get the fields:
#Entity
#Component
#Data
#EqualsAndHashCode(callSuper = false)
#Table(name = "m_loan", uniqueConstraints = { #UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"),
#UniqueConstraint(columnNames = { "external_id" }, name = "loan_externalid_UNIQUE") })
public class Loan extends AbstractPersistableCustom<Long> {
#Column(name = "account_no", length = 20, unique = true, nullable = false)
private String accountNumber;
}
The id is inside the AbstractPersistableCustom class which is being extended inside Loan.java.
This is BillingProcessInterface.java where I call the LoanInterface.java
#JsonPropertyOrder({
"id",
"loanId"
})
public interface BillingProcessInterface {
public Long getId();
public LoanInterface getLoanId();
}
BillingProcess.java model, where I call the Loan.java
#Entity
#Table(name = "m_billing")
#Data
#EqualsAndHashCode(callSuper = true)
public class BillingProcess extends AbstractPersistableCustom<Long> {
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "loan_id", nullable = false)
private Loan loanId;
}
The getId from LoanInterface.java works:
But when I try to get other fields from Loan.java like the accountNumber, I am getting the error.
Does anyone have an idea how to resolve this? Have I overused or lacked something regards the usage of annotation?
Thank you.
Looks like you're trying to do projection from lazy loaded field.
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "loan_id", nullable = false)
private Loan loanId;
Projection happens outside transaction so you have to have loaded fields before you use them. You can achieve it by changing fetch type to EAGER or use '#EntityGraph' annotation in repository to specify which lazy fields should be loaded.
In my Spring boot - JPA application, I am trying to implement composite key :
#Entity
public class User
{
#Id
private String timeStamp;
#Id
private String firstName;
#Id
private String lastName;
}
This gives me error, saying :
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Composite-id class must implement Serializable: com.mua.testkeys.model.User
Even if I implement Serializable it gives me error.
How can I resolve this ?
Used : Spring + JPA + H2
Composite Key can be created with #IdClass as below.
User.class
#IdClass(UserPK.class)
#Table(name = "user")
#Entity
public class User {
#Id
private String timeStamp;
#Id
private String firstName;
#Id
private String lastName;
//remaining fields
// getters and setters
}
UserPK.class
public class UserPK {
private String timeStamp;
private String firstName;
private String lastName;
// constructors
// getters and setters
//implement euquels() and hashcode()
}
Define a Class for primary key with all keys as fields.
Implement equals() and hashcode() methods.
Annotate User class with #IdClass(UserPK.class)
Declare Id fields with #Id annotation