org.springframework.beans.factory.BeanCreationException: in Ecommerce project - java

I work with a Spring boot project and when I run, I get the following error,
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userSecurityService': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract Ecommerce.entities.User Ecommerce.repository.UserRepository.findByUsername(java.lang.String)!
I assume the last lines are what is important in the error stack,
Could not create query metamodel for method public abstract Ecommerce.entities.User Ecommerce.repository.UserRepository.findByUsername(java.lang.String)!
I have the User repository provided below,
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
User findByEmail(String email);
}
The user entity is also provided,
#Entity
public class User implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "userId", nullable = false, updatable = false)
private Long userId;
private String userName;
private String password;
private String firstName;
private String lastName;
#Column(name = "email", nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled = true;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
private ShoppingCart shoppingCart;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserShipping> userShippingList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserPayment> userPaymentList;
#OneToMany(mappedBy = "user")
private List<Order> orderList;
#JsonIgnore
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<UserRole> userRoles = new HashSet<>();
// ..............
// more lines of code for overriding the methods
}
What is the issue here and how to solve it?

In Spring JPA Repository, the auto-generated finders obey the naming convention as follows.
findBy<DataMember><Op>
<Op> can be Like,Between etc..

Apparently, the name of the method findByUsername should match with the property in the user entity. In the user entity class, I have used,
#Entity
public class User implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "userId", nullable = false, updatable = false)
private Long userId;
private String userName;
}
After I changed to the username from the userName, the problem is solved. I have done this after consulting other SOF posts, but, I still seek for the better explanation.

Related

Getting an error "Not a managed type: class java.lang.Long"

In short, I try make authorization with Spring security. But I get error
Caused by: java.lang.IllegalArgumentException: Not a managed type: class java.lang.Long
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleRepository': Invocation of init method failed;
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDetailsServiceImpl': Unsatisfied dependency expressed through field 'roleRepository';
Interface RoleRepository implements methods from JpaRepository.
https://github.com/TimurShubin/cbrparser/blob/master/src/main/java/com/cbr/converter/repositories/RoleRepository.java
#Repository
public interface RoleRepository extends JpaRepository<Long, Roles>{
#Query("select r from roles r where id = 1")
public List<Roles> getRole(long userId);
}
It's associated with UserDetailsServiceImpl class, which implements loadUserByUsername method. In this method I getting user data (role, username, password).
I think that problem in entities classes (Roles, Users, UserRole), there I use OneToMany binding: UserRole consists user_id and role_id fields, which associated with Users and Roles tables repsectively. I don't understand, where exactly is the error.
UserRole:
#Entity
#Table(name = "user_role")
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id", nullable = false)
private Users users;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "role_id", nullable = false)
private Roles roles;
// getters, setters
}
Roles:
#Entity
#Table(name = "roles")
public class Roles {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#OneToMany(mappedBy = "roles")
private Set<UserRole> roles;
// getters, setters
}
Users:
#Entity
#Table(name = "users")
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long uid;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "enabled")
private boolean enabled;
#OneToMany(mappedBy = "users")
private Set<UserRole> users;
// getters, setters
}
You have RoleRepository class as below
#Repository
public interface RoleRepository extends JpaRepository<Long, Roles>{
#Query("select r from roles r where id = 1")
public List<Roles> getRole(long userId);
}
which needs to be changed as below because the the spring managed entity type Roles need to be the first argument.
#Repository
public interface RoleRepository extends JpaRepository<Roles, Long>{
#Query("select r from roles r where id = 1")
public List<Roles> getRole(long userId);
}

How to set a domain field as a list of numbers

I want to define one field within the question_response table as a list of numbers.
#Entity
public class QuestionResponse {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name="question_response_id", nullable = false, updatable = false)
private Long question_response_id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_uuid")
private User users;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "question_id")
private Question questions;
private List<Long> questionAns;
}
But it gave the error of:
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; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: question_response, for columns: [org.hibernate.mapping.Column(question_ans)]
I've also tried Set, but didn't work. Can anybody help me with this?
you can use this :
public class Answer{
#Column(name="id_response")
private long Idresponse;
#Column(name="response")
private String response;
#JsonIgnore
#ManyToOne
#JoinColumn(name="question")
private QuestionResponse questionResponse;
}
then in QuestionResponse class you can you use OneToMany relation as shown , it will work :
#Entity
public class QuestionResponse {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name="question_response_id", nullable = false, updatable = false)
private Long question_response_id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_uuid")
private User users;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "question_id")
private Question questions;
#OneToMany(mappedBy = "answer", cascade = CascadeType.ALL)
private Set<Answer> answer;
}

Spring boot + jpa +mysql error on aws or openshift

I tried to deploy my application on AWS and Openshift, the applications seems to work fine until I try to access GET /users endpoint after a POST (saved user without company data).
It returns:
There was an unexpected error (type=Internal Server Error, status=500).
could not prepare statement; SQL [select companies0_.users_id as users_id1_8_0_, companies0_.companies_id as companie2_8_0_, company1_.id as id1_0_1_, company1_.contact_id as contact_4_0_1_, company1_.gallery_id as gallery_5_0_1_, company1_.active as active2_0_1_, company1_.promoted as promoted3_0_1_, company1_.location_id as location6_0_1_, company1_.profile_id as profile_7_0_1_, company1_.subscription_id as subscrip8_0_1_, contact2_.id as id1_1_2_, contact2_.email as email2_1_2_, contact2_.phone as phone3_1_2_, gallery3_.id as id1_2_3_, location4_.id as id1_3_4_, location4_.address as address2_3_4_, location4_.city as city3_3_4_, location4_.country as country4_3_4_, location4_.country_code as country_5_3_4_, location4_.latitude as latitude6_3_4_, location4_.longitude as longitud7_3_4_, profile5_.id as id1_5_5_, profile5_.company_category as company_2_5_5_, profile5_.creation_date as creation3_5_5_, profile5_.description as descript4_5_5_, profile5_.name as name5_5_5_, profile5_.thumbnail as thumbnai6_5_5_, subscripti6_.id as id1_6_6_, subscripti6_.subscription_end_date as subscrip2_6_6_, subscripti6_.subscription_start_date as subscrip3_6_6_ from users_companies companies0_ inner join companies company1_ on companies0_.companies_id=company1_.id left outer join contacts contact2_ on company1_.contact_id=contact2_.id left outer join gallery gallery3_ on company1_.gallery_id=gallery3_.id left outer join locations location4_ on company1_.location_id=location4_.id left outer join profiles profile5_ on company1_.profile_id=profile5_.id left outer join subscription subscripti6_ on company1_.subscription_id=subscripti6_.id where companies0_.users_id=?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
The logs are as follows:
org.springframework.dao.InvalidDataAccessResourceUsageException:could not prepare statement
Caused by: java.sql.SQLSyntaxErrorException:user lacks privilege or object not found:COMPANIES in statement
Caused by: org.hsqldb.HsqlException:user lacks privilege or object not found:COMPANIES
But all these works perfectly fine on local server with mysql.
The controller:
#RestController
public class UserController {
#Autowired
UserRepository repository;
#GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity getUsers() {
return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
}
}
Repository:
#Repository
public interface UserRepository extends JpaRepository<User, String> {
}
User model:
#Entity
#Table(name = "users")
#DynamicUpdate
#EntityListeners(AuditingEntityListener.class)
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false)
#SerializedName("id")
private long id;
#Column(name = "name")
#SerializedName("name")
private String name;
#Column(name = "email", unique = true, updatable = false)
#SerializedName("email")
private String email;
#Column(name = "password")
#SerializedName("password")
#JsonIgnore
private String password;
#Column(name = "accessToken")
#SerializedName("accessToken")
private String accessToken;
#Column(name = "phoneNumber")
#SerializedName("phoneNumber")
private String phoneNumber;
#Column(name = "createdAt", nullable = false, updatable = false)
#SerializedName("createdAt")
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private Date createdAt;
#Column(name = "updatedAt", nullable = false)
#SerializedName("updatedAt")
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private Date updatedAt;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Company> companies;
//getters & setters etc
}
Company model:
#Entity
#Table(name = "companies")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false)
#SerializedName("id")
private long id;
#OneToOne(cascade = CascadeType.ALL)
#SerializedName("profile")
private Profile profile;
#OneToOne(cascade = CascadeType.ALL)
#SerializedName("contact")
private Contact contact;
#OneToOne(cascade = CascadeType.ALL)
#SerializedName("location")
private Location location;
#OneToOne(cascade = CascadeType.ALL)
#SerializedName("gallery")
private Gallery gallery;
#OneToOne(cascade = CascadeType.ALL)
#SerializedName("subscription")
private Subscription subscription;
#Column(name = "active", columnDefinition = "tinyint(1) default 0")
#SerializedName("active")
private boolean isActive;
#Column(name = "promoted", columnDefinition = "tinyint(1) default 0")
#SerializedName("promoted")
private boolean isPromoted;
//getters & setters etc
}
Application properties:
spring.datasource.url=jdbc:mysql://host:3306/database
spring.datasource.username=user
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
Any idea what cause this problem? Also I mentioned above this works perfectly fine on local machine.
UPDATE Its seems if I don't provide data for every object in relations when saving (exp.User/Company,Company/Profile,Company/Contact etc) a user to db it gives this error.

Spring boot / Hibernate problems with #UniqueConstraint

I have Spring boot 1.4.3 + Hibernate 5.0.11 + H2 database.
My application startup fails when I try to use #UniqueConstraint with certain values. Here is it. Response class is marked with #UniqueConstraint with columnNames "survey" and "user"
#Entity
#Table(name = "responses", uniqueConstraints = {#UniqueConstraint(columnNames = {"survey, user"}, name = "responses_survey_user_idx")})
public class Response extends BaseEntity
{
#NotNull
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "survey", nullable = false)
private Survey survey;
#NotNull
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "user", nullable = false)
private User user;
#NotNull
private String answers;// json serialized
}
Survey class:
#Entity
#Table(name = "surveys", uniqueConstraints = {#UniqueConstraint(columnNames = {"name"}, name = "surveys_name_idx")})
public class Survey extends BaseEntity{
#NotNull
#SafeHtml
#Length(min = 3)
private String name;
#NotNull
#SafeHtml
#Length(min = 3)
private String description;
#OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, mappedBy = "survey")
private List<Response> responses;
}
User class:
#Entity
#Table(name = "users", uniqueConstraints = {#UniqueConstraint(columnNames = "login", name = "users_unique_email_idx")})
public class User extends BaseEntity {
#NotEmpty
#SafeHtml
private String login;
#NotEmpty
#Length(min = 8)
#SafeHtml
private String password;
#OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, mappedBy = "user")
private List<Response> responses;
}
The error I get is:
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 org.hibernate.AnnotationException: Unable to create unique key constraint (survey, user) on table responses: database column 'survey, user' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
I've tried to change names of columns in Response class, but it didn't help.
It work only when I remove #UniqueConstraint in this class at all .
Any ideas how to deal with this?
The column names in your unique constraint should not be comma separated but rather separate String values in an array (see http://docs.oracle.com/javaee/6/api/javax/persistence/UniqueConstraint.html):
#Table(
name="EMPLOYEE",
uniqueConstraints=
#UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)

Invalid custom update query defined in Spring Data JPA CrudRepository

I have a custom JPQL query in a Spring CrudRepository that's not working.
This is my entity class, PK class and CrudRepository interface for the entity:
#Entity(name = "TBL_PRINCIPAL_CREDENTIAL")
public class PrincipalCredential {
#EmbeddedId
private PrincipalCredentialPK principalCredentialPK;
// ...getter & setter for principalCredentialPK
}
#Embeddable
public class PrincipalCredentialPK implements Serializable {
#Column(name = "PRINCIPAL_TYPE_ID", nullable = false)
private String principalTypeID;
#Column(name = "PRINCIPAL_ID", nullable = false)
private String principalID;
#Column(name = "CREDENTIAL_ID", nullable = false)
private Integer credentialID;
#Column(name = "CREDENTIAL_TYPE_ID", nullable = false)
private String credentialTypeID;
// ...getters & setters for all fields...
}
#Transactional
public interface PrincipalCredentialRepository extends CrudRepository<PrincipalCredential, PrincipalCredentialPK> {
#Modifying
#Query("update PrincipalCredential pc set pc.principalCredentialPK.principalID =:newPrincipalID " +
"where pc.principalCredentialPK.principalID =:oldPrincipalID and pc.principalCredentialPK.principalTypeID =:principalType")
void updatePrincipalID(#Param("oldPrincipalID") String oldPrincipalID, #Param("newPrincipalID") String newPrincipalID,
#Param("principalType") String principalType);
}
When I start my project using SpringBoot the repository bean cannot be instantiated and I get the following exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'principalCredentialRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract void com.consorsbank.services.banking.caas.repositories.PrincipalCredentialRepository.updatePrincipalID(java.lang.String,java.lang.String,java.lang.String)!
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract void com.consorsbank.services.banking.caas.repositories.PrincipalCredentialRepository.updatePrincipalID(java.lang.String,java.lang.String,java.lang.String)!
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: PrincipalCredential is not mapped [update PrincipalCredential pc set pc.principalCredentialPK.principalID =:newPrincipalID where pc.principalCredentialPK.principalID =:oldPrincipalID and pc.principalCredentialPK.principalTypeID =:principalType]
Also for another repository this query is working, the difference is that the PK of the other entity is simpler and both ids are provided there...
#Entity
#Table(name = "TBL_PRINCIPALS")
public class Principal implements Serializable {
#EmbeddedId
private PrincipalPK principalPK;
#OneToOne
#JoinColumn(name = "PRINCIPAL_TYPE_ID", insertable = false, updatable = false)
private PrincipalType principalType;
#Column(name = "USER_ID")
private Integer userID;
#Column(name = "VALID_UNTIL")
private Date validUntil;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "ZAAS_TBL_PRINCIPAL_CREDENTIAL",
joinColumns = {#JoinColumn(name = "PRINCIPAL_ID"), #JoinColumn(name = "PRINCIPAL_TYPE_ID")},
inverseJoinColumns = {#JoinColumn(name = "CREDENTIAL_ID"), #JoinColumn(name="CREDENTIAL_TYPE_ID")})
public Set<Credential> credentials;
// ...getters and setters...
}
#Embeddable
public class PrincipalPK implements Serializable {
#Column(name = "PRINCIPAL_TYPE_ID", nullable = false)
private String principalTypeID;
#Column(name = "PRINCIPAL_ID", nullable = false)
private String principalID;
// ...getters and setters
}
#Transactional
public interface PrincipalsRepository extends CrudRepository<Principal, PrincipalPK> {
#Modifying
#Query("update Principal p set p.principalPK.principalID =:newPrincipalID " +
"where p.principalPK.principalID =:oldPrincipalID and p.principalPK.principalTypeID =:principalType")
void updatePrincipalID(#Param("oldPrincipalID") String oldPrincipalID, #Param("newPrincipalID") String newPrincipalID,
#Param("principalType") String principalType);
}
So the above query is working...
Could someone please point out what I'm missing for the query defined in the PrincipalCredentialRepository?
The entity definition seems to be wrong. Use the following annotations
#Entity
#Table(name = "TBL_PRINCIPAL_CREDENTIAL")
public class PrincipalCredential {
//...

Categories

Resources