Hi everyone, I'm stuck in Spring-Data-JPA for two days, finally realized I can probably get some helps from here.
How to get Repository from outside the spring container(standalone). I have try the code from this example. I got Exception in thread "main" java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
I have also try with the following code
UserGrantedAuthority authority = new UserGrantedAuthority("admin");
ApplicationContext context = SpringContext.getContext();
UserGrantedAuthorityRepository repo = new JpaRepositoryFactory(context.getBean(EntityManager.class)).getRepository(UserGrantedAuthorityRepository.class);
repository.save(authority);
Then I get Exception in thread "main" javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
When I try to save my User entity into database with my UserRepository , I got the error below
Hibernate: select user0_.username as username1_0_3_, user0_.authorities as authorit7_0_3_, user0_.enabled as enabled2_0_3_, user0_.expired as expired3_0_3_, user0_.locked as locked4_0_3_, user0_.password as password5_0_3_, user0_.vaild_password as vaild_pa6_0_3_, usergrante1_.id as id1_1_0_, usergrante1_.authorities as authorit2_1_0_, usergrante1_.user as user3_1_0_, usergrante2_.id as id1_2_1_, usergrante2_.authority as authorit2_2_1_, user3_.username as username1_0_2_, user3_.authorities as authorit7_0_2_, user3_.enabled as enabled2_0_2_, user3_.expired as expired3_0_2_, user3_.locked as locked4_0_2_, user3_.password as password5_0_2_, user3_.vaild_password as vaild_pa6_0_2_ from user user0_ left outer join user_granted_authorities usergrante1_ on user0_.authorities=usergrante1_.authorities left outer join user_granted_authority usergrante2_ on usergrante1_.authorities=usergrante2_.authority left outer join user user3_ on usergrante1_.user=user3_.username where user0_.username=?
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: Error accessing field [private int com.storechain.spring.boot.entity.UserGrantedAuthority.id] by reflection for persistent property [com.storechain.spring.boot.entity.UserGrantedAuthority#id] : [admin]; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private int com.storechain.spring.boot.entity.UserGrantedAuthority.id] by reflection for persistent property [com.storechain.spring.boot.entity.UserGrantedAuthority#id] : [admin]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy135.save(Unknown Source)
at com.storechain.EntryPoint.main(EntryPoint.java:169)
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private int com.storechain.spring.boot.entity.UserGrantedAuthority.id] by reflection for persistent property [com.storechain.spring.boot.entity.UserGrantedAuthority#id] : [admin]
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:75)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:230)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5280)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:150)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:853)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:826)
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:261)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:510)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:434)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:220)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:153)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:427)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:240)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:175)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:853)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:826)
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:261)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:510)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:434)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:220)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:153)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:427)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:240)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:833)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:820)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
at jdk.proxy2/jdk.proxy2.$Proxy127.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:633)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 8 more
Caused by: java.lang.IllegalArgumentException: Can not set int field com.storechain.spring.boot.entity.UserGrantedAuthority.id to java.util.ImmutableCollections$ListN
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at java.base/jdk.internal.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56)
at java.base/java.lang.reflect.Field.getInt(Field.java:601)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:62)
... 66 more
Repositoroes:
ExtensionRepository.java
package com.storechain.interfaces.spring.repository;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
#NoRepositoryBean
public interface ExtensionRepository<T, ID extends Serializable> extends JpaRepository<T,ID>, JpaSpecificationExecutor<T> {
}
UserRepository.java
package com.storechain.interfaces.spring.repository;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.query.Param;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;
import com.storechain.spring.boot.entity.User;
#Repository
public interface UserRepository extends ExtensionRepository<User, String>, UserDetailsService {
#Transactional
#Modifying
default UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return findByUsernameIgnoreCase(username);
}
User findByUsernameIgnoreCase(#Param("username") String username);
}
UserGrantedAuthorityRepository.java
package com.storechain.interfaces.spring.repository;
import org.springframework.stereotype.Repository;
import com.storechain.spring.boot.entity.UserGrantedAuthority;
#Repository
public interface UserGrantedAuthorityRepository extends ExtensionRepository<UserGrantedAuthority, Integer> {
}
UserAuthoritiesRepository.java
package com.storechain.interfaces.spring.repository;
import org.springframework.stereotype.Repository;
import com.storechain.spring.boot.entity.UserGrantedAuthorities;
#Repository
public interface UserAuthoritiesRepository extends ExtensionRepository<UserGrantedAuthorities, Long> {
}
Entities:
User.java
package com.storechain.spring.boot.entity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
#Entity
public class User implements UserDetails {
#Id
private String username;
#Column(nullable = false)
private String password;
#OneToOne(targetEntity = UserGrantedAuthorities.class, cascade = CascadeType.ALL)
#JoinColumn(name = "authorities", referencedColumnName = "authorities")
private UserGrantedAuthorities authorities;
private boolean expired;
private boolean locked;
private boolean vaildPassword;
private boolean enabled;
public User() {}
public User(String username, String password, Collection<? extends GrantedAuthority> authorities, boolean expired, boolean locked, boolean vaildPassword, boolean enabled) {
this.username = username;
this.password = password;
this.authorities = new UserGrantedAuthorities(this, authorities);
this.expired = expired;
this.locked = locked;
this.vaildPassword = vaildPassword;
this.enabled = enabled;
}
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, authorities, false, false, true, true);
}
public User(String username, String password, GrantedAuthority... authorities) {
this(username, password, Arrays.stream(authorities).toList());
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public Collection<GrantedAuthority> getAuthorities() {
return (Collection<GrantedAuthority>) authorities.getAuthorities();
}
public void setAuthorities(UserGrantedAuthorities authorities) {
this.authorities = authorities;
}
#Override
public boolean isAccountNonExpired() {
return !this.expired;
}
#Override
public boolean isAccountNonLocked() {
return !this.locked;
}
#Override
public boolean isCredentialsNonExpired() {
return !this.vaildPassword;
}
#Override
public boolean isEnabled() {
return this.enabled;
}
public boolean isExpired() {
return expired;
}
public void setExpired(boolean exipired) {
this.expired = exipired;
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public boolean isVaildPassword() {
return vaildPassword;
}
public void setVaildPassword(boolean vaildPassword) {
this.vaildPassword = vaildPassword;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#Override
public String toString() {
return super.toString() + "(" + this.username + ")";
}
}
UserGrantedAuthorities.java
package com.storechain.spring.boot.entity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.springframework.security.core.GrantedAuthority;
#Entity
public class UserGrantedAuthorities {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#OneToOne(targetEntity = User.class, cascade = CascadeType.ALL)
#JoinColumn(name = "user", referencedColumnName = "username")
private User user;
#ManyToOne(targetEntity = UserGrantedAuthority.class, cascade = CascadeType.ALL)
#JoinColumn(name = "authorities", referencedColumnName = "authority")
#ElementCollection
private Collection<UserGrantedAuthority> authorities;
public UserGrantedAuthorities() {}
public UserGrantedAuthorities(User user, Collection<? extends GrantedAuthority> authorities) {
this.user = user;
this.authorities = authorities.stream().map(role -> new UserGrantedAuthority(role.getAuthority())).toList();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(Collection<UserGrantedAuthority> authorities) {
this.authorities = new ArrayList<UserGrantedAuthority>(authorities);
}
public <T extends GrantedAuthority> void addAuthority(T... authorities) {
this.authorities = Arrays.stream(authorities).map(role -> new UserGrantedAuthority(role.getAuthority())).toList();
}
}
UserGrantedAuthority.java
#Entity
public class UserGrantedAuthority implements GrantedAuthority {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String authority;
public UserGrantedAuthority() {}
public UserGrantedAuthority(String authority) {
this.authority = authority;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public String getAuthority() {
return this.authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof SimpleGrantedAuthority) {
return this.authority.equals(((SimpleGrantedAuthority) obj).getAuthority());
}
if(obj instanceof UserGrantedAuthority) {
return this.authority.equals(((UserGrantedAuthority)obj).getAuthority());
}
return false;
}
#Override
public int hashCode() {
return this.authority.hashCode();
}
#Override
public String toString() {
return this.authority;
}
}
Configurations:
PersistenceConfiguration.java
package com.storechain.spring.boot.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.storechain.interfaces.spring.repository.UserGrantedAuthorityRepository;
import com.storechain.interfaces.spring.repository.UserRepository;
import com.storechain.spring.boot.service.JpaExtensionRepository;
#Configuration
#ConfigurationProperties("spring")
#EnableJpaRepositories(value = "com.storechain.interfaces.spring.repository", repositoryBaseClass = JpaExtensionRepository.class)
public class PersistenceConfiguration {
private DataSourceConfiguration datasource;
private JpaConfiguration jpa;
public DataSourceConfiguration getDatasource() {
return datasource;
}
public void setDatasource(DataSourceConfiguration datasource) {
this.datasource = datasource;
}
public JpaConfiguration getJpa() {
return jpa;
}
public void setJpa(JpaConfiguration jpa) {
this.jpa = jpa;
}
public UserRepository getRepo() {
return repo;
}
public UserGrantedAuthorityRepository getAnotherRepo() {
return anotherRepo;
}
#Autowired
private UserRepository repo;
#Autowired
private UserGrantedAuthorityRepository anotherRepo;
public static class DataSourceConfiguration {
private String driverClassName;
private String url;
private String username;
private String password;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public static class JpaConfiguration {
private HibernateConfiguration hibernate;
private Boolean showSql;
public static class HibernateConfiguration {
private String ddlAuto;
public String getDdlAuto() {
return ddlAuto;
}
public void setDdlAuto(String ddlAuto) {
this.ddlAuto = ddlAuto;
}
}
public HibernateConfiguration getHibernate() {
return hibernate;
}
public void setHibernate(HibernateConfiguration hibernate) {
this.hibernate = hibernate;
}
public Boolean getShowSql() {
return showSql;
}
public void setShowSql(Boolean showSql) {
this.showSql = showSql;
}
}
}
JpaExtensionRepository.java
package com.storechain.spring.boot.service;
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import com.storechain.interfaces.spring.repository.ExtensionRepository;
public class JpaExtensionRepository<T, ID extends Serializable> extends SimpleJpaRepository<T,ID> implements ExtensionRepository<T,ID> {
private final EntityManager entityManager;
public JpaExtensionRepository(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
public JpaExtensionRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager em) {
super(entityInformation, em);
this.entityManager = em;
}
}
Sorry too many characters,
application.yml and
pom.xml can only with hyperlinks.
I have try to save entity of UserGrantedAuthority by using #Autowired to UserGrantedAuthorityRepository and it was worked! So I think there must be something wrong with my configurations in User or UserGrantedAuthorities class
Thank you for your time!!
Related
Hi people I am working on one application .I have created a model but after giving all annotation and configuring all properties it is showing below error. Can anyone please look into below issue?
application.properties
spring.datasource.url = jdbc:mysql://localhost:3306/expenses
spring.datasource.username =dante
spring.datasource.password =jboss
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.format_sql=true
server.port=9191
Main Class
package com.expenses.demo;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.expenses.demo.modal.Role;
import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;
import com.expenses.service.UserService;
#SpringBootApplication
public class ExpenseApplication implements CommandLineRunner {
#Autowired
private UserService userService;
public static void main(String[] args) {
SpringApplication.run(ExpenseApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("Starting code");
User user = new User();
user.setFirstname("Aniket");
user.setLastname("Turiley");
user.setEmail("abc#gmail.com");
user.setPassword("abc");
user.setPhone("99220289");
Role role1=new Role();
role1.setRoleId(44L);
role1.setRoleName("ADMIN");
Set<UserRole> userRoleSet = new HashSet<>();
UserRole userRole = new UserRole();
userRole.setRole(role1);
userRole.setUser(user);
userRoleSet.add(userRole);
User user1= this.userService.createUser(user,userRoleSet);
System.out.println(user1.getUsername());
}
}
Model Class
Role.java
package com.expenses.demo.modal;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="roleinformation")
public class Role {
#Id
private long roleId;
private String roleName;
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "role")
private Set<UserRole> userRoles = new HashSet<>();
public Role() {
}
public Role(int roleId, String roleName) {
this.roleId = roleId;
this.roleName = roleName;
}
public long getRoleId() {
return roleId;
}
public void setRoleId(long l) {
this.roleId = l;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
User.java
package com.expenses.demo.modal;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name="usersinfo")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
private String username;
private String password;
private String email;
private String phone;
private boolean enable=true;
// user has many roles
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "user")
#JsonIgnore
private Set<UserRole> userRoles = new HashSet<>();
public User() {
}
public User(Long id, String firstname, String lastname, String username, String password, String email,
String phone, boolean enable) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.username = username;
this.password = password;
this.email = email;
this.phone = phone;
this.enable = enable;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
Repository Interfaces
RoleRepository
package com.expenses.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.expenses.demo.modal.Role;
public interface RoleRepository extends JpaRepository<Role, Long>{
}
UserRepository
package com.expenses.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.expenses.demo.modal.User;
public interface UserRepository extends JpaRepository<User, Long> {
public User findByUsername(String username);
}
Service Class
Service.java
package com.expenses.service;
import java.util.Set;
import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;
public interface UserService {
//creating user
public User createUser(User user,Set<UserRole> userRoles) throws Exception;
}
Service Implementation class
ServiceImplementation.java
package com.expenses.service;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.expenses.demo.modal.User;
import com.expenses.demo.modal.UserRole;
import com.expenses.repository.RoleRepository;
import com.expenses.repository.UserRepository;
import com.expenses.service.UserService;
#Service
public class UserServiceImplementation implements UserService{
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Override
public User createUser(User user, Set<UserRole> userRoles) throws Exception{
User local= this.userRepository.findByUsername(user.getUsername());
if(local!=null) {
System.out.println("User Already Exist");
throw new Exception("User Already Exist");
}else {
// user create
for(UserRole ur:userRoles) {
roleRepository.save(ur.getRole());
}
user.getUserRoles().addAll(userRoles);
local = this.userRepository.save(user);
}
return local;
}
}
ERROR
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[2m2021-07-28 18:16:59.304[0;39m [31mERROR[0;39m [35m8492[0;39m [2m---[0;39m [2m[ restartedMain][0;39m [36mo.s.b.d.LoggingFailureAnalysisReporter [0;39m [2m:[0;39m
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userService in com.expenses.demo.ExpenseApplication required a bean of type 'com.expenses.service.UserService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.expenses.service.UserService' in your configuration.
Spring Boot will do the component scan (search for Classes with #Service, #Repository, #Controller, #Component) annotation only classes that are located in the same package as the main class (#SpringBootApplication annoteted class), and its subpackages.
So you need eighter to
move ExpenseApplication one package up, to com.expenses,
move all classes that needs to be found by the component scan to to com.expenses.demo or a subpackage, or
configure the component scan (and Spring Data too), for example, by #SpringBootApplication(scanBasePackages = "com.expenses")
BTW: Najeeb Arif is right too, in addition you need to add #Autowired to UserServiceImplementation.userRepository but I think you do not need to add the #Repository annotation to the Spring-Data-JPA repository interfaces.
Add this to your main class
#SpringBootApplication(scanBasePackages = "com.expenses")
This will help the component scan will find your classes.
First mark both of your Repositories with
#Repository
In your user service, you are missing the Autowired annotation.
I personally like the constructor injection.
Role Repository
#Repository
public interface RoleRepository extends JpaRepository<Role, Long>{
}
Same for the user repo.
in your User Service Impl
#Service
public class UserServiceImplementation implements UserService{
private final UserRepository userRepository;
private final RoleRepository roleRepository;
/* when using constructor injection #Autowired is not required */
public UserServiceImplementation(UserRepository userRepository, RoleRepository roleRepository){
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
#Override
public User createUser(User user, Set<UserRole> userRoles) throws Exception{
//...
}
}
The method getUserAuthority(java.util.Set<com.djamware.springsecuritymongodb.domain.Role>) in the type CustomUserDetailsService is not applicable for the arguments (java.util.Set<javax.management.relation.Role>)
Why giving this error?
This Java file is under package com.djamware.springsecuritymongodb.services and User.java is under package com.djamware.springsecuritymongodb.domain
package com.djamware.springsecuritymongodb.services;
import com.djamware.springsecuritymongodb.domain.Role;
import com.djamware.springsecuritymongodb.domain.User;
import com.djamware.springsecuritymongodb.repositories.RoleRepository;
import com.djamware.springsecuritymongodb.repositories.UserRepository;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
#Service
public class CustomUserDetailsService implements UserDetailsService{
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public User findUserByEmail(String email) {
return userRepository.findByEmail(email);
}
public void saveUser(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
user.setEnabled(true);
Role userRole = roleRepository.findByRole("ADMIN");
// user.setRoles(new HashSet<>(Arrays.asList(userRole)));
user.setRoles(new HashSet<Role>(Arrays.asList(userRole)));
userRepository.save(user);
}
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userRepository.findByEmail(email);
if(user != null) {
List<GrantedAuthority> authorities = getUserAuthority(user.getRoles());
return buildUserForAuthentication(user, authorities);
} else {
throw new UsernameNotFoundException("username not found");
}
}
private List<GrantedAuthority> getUserAuthority(Set<Role> userRoles) {
Set<GrantedAuthority> roles = new HashSet<GrantedAuthority>();
for (Role role : userRoles) {
roles.add(new SimpleGrantedAuthority(role.getRole()));
}
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(roles);
return grantedAuthorities;
}
private UserDetails buildUserForAuthentication(User user, List<GrantedAuthority> authorities) {
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), authorities);
}
}
I have created User Class attached here.
User.java
package com.djamware.springsecuritymongodb.domain;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.IndexDirection;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.management.relation.Role;
#Document(collection = "user")
public class User {
#Id
private String id;
#Indexed(unique = true, direction = IndexDirection.DESCENDING, dropDups = true)
private String email;
private String password;
private String fullname;
private boolean enabled;
#DBRef
private Set<Role> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public void setRoles(HashSet<com.djamware.springsecuritymongodb.domain.Role> hashSet) {
// TODO Auto-generated method stub
}
}
The reason is that the Role that CustomUserDetailsServices getUserAuthority(Set<Role> userRoles) is expecting com.djamware.springsecuritymongodb.domain.Role (see its imports). However, User is returning javax.management.relation.Role (see its imports). To fix it, remove import javax.management.relation.Role; from the User class. Since User and Role are in the same package you don't need to explicitly import anything.
I tried to add One To Many Annotation to my spring boot project, but when I run my project I get "Failed to execute CommandLineRunner " error.
I wanted users in the user's table to have more than one city. So, I tried to add OneToMany Annotation.
You can see the error at the attachment.
User Class
package io.javabrains.springsecurity.jpa.models;
import com.spring.weather.*;
import java.util.*;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="app_user")
public class User {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int id;
private String userName;
private String password;
private boolean active;
private String role;
private String city;
#OneToMany(targetEntity = UserCity.class,cascade = CascadeType.ALL)
#JoinTable(name="USER_CITY",joinColumns=#JoinColumn(name="m_user_id"),
inverseJoinColumns=#JoinColumn(name="cityId"))
private List<UserCity> usercity;
public User() {
super();
// TODO Auto-generated constructor stub
}
public List<UserCity> getUsercity() {
return usercity;
}
public void setUsercity(List<UserCity> usercity) {
this.usercity = usercity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
User City Class
package io.javabrains.springsecurity.jpa.models;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="user_city")
public class UserCity {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int cityId;
private String cityName;
public UserCity() {
super();
// TODO Auto-generated constructor stub
}
public UserCity(int cityId, String cityName, User mUser) {
super();
this.cityId = cityId;
this.cityName = cityName;
this.mUser = mUser;
}
#ManyToOne
private User mUser;
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public User getmUser() {
return mUser;
}
public void setmUser(User mUser) {
this.mUser = mUser;
}
}
User Repository
package io.javabrains.springsecurity.jpa;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import io.javabrains.springsecurity.jpa.models.User;
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUserName(String userName);
}
User City Repository
package io.javabrains.springsecurity.jpa;
import org.springframework.data.jpa.repository.JpaRepository;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
public interface CityRepository extends JpaRepository<UserCity,id>{
}
Spring Application Class
package io.javabrains.springsecurity.jpa;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.spring.weather.WeatherService;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
#SpringBootApplication
#EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SpringsecurityApplication implements CommandLineRunner{
#Bean
public WeatherService ws() {
return new WeatherService ();
}
#Autowired
UserRepository userRepository;
CityRepository cityRepository;
public static void main(String[] args) {
SpringApplication.run(SpringsecurityApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("Application Running.");
User adminUser= new User();
UserCity ucity=new UserCity();
UserCity ucity2=new UserCity();
ucity.setCityName("amsterdam");
adminUser.setUserName("Admin");
adminUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
adminUser.setRole("ROLE_ADMIN");
adminUser.setActive(true);
adminUser.setCity("bologna");
ucity.setmUser(adminUser);
userRepository.save(adminUser);
cityRepository.save(ucity);
User newUser= new User();
newUser.setUserName("User");
newUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newUser.setRole("ROLE_USER");
newUser.setActive(true);
newUser.setCity("maribor");
ucity2.setmUser(newUser);
userRepository.save(newUser);
cityRepository.save(ucity2);
}
}
The problem you are encountering, more specifically the NullPointerException at line 54 of your main application, is caused by the fact that the cityRepository is not
instantiated.
Looking through your configuration, I see that you only register the UserRepository with the #EnableJpaRepositories annotation.
Try adding also the CityRepository to the #EnableJpaRepositories, and also specify this bean as a candidate for autowiring( also add #Autowired to this bean, as you did for UserRepository)
For a good practice, following the MVC structure, it would be nice is all your spring repositories, the beans responsible for all CRUD operations with the database to be under the same package
This test project becouse of I don't know how I inject #AuthenticationPrincipal annotation in method ,I have some problem,#AuthenticationPrincipal UserDetails throws exception
UserDetails userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal()
is working not problem but I want to inject this annotation in method how can I do ?
When I added annotation in method this exception is thrown
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.security.core.userdetails.UserDetails
How can I inject #AuthenticationPrincipal to index method in MainControll class ?
How can I solve this situation ?
MainControll.class
package com.sencerseven.springsecurityauth.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class MainController {
#RequestMapping(value = {"/"})
public ModelAndView index(#AuthenticationPrincipal UserDetails userDetails) {
ModelAndView mv = new ModelAndView("index");
mv.addObject("user", userDetails);
return mv;
}
#RequestMapping(value = {"/login"})
public ModelAndView loginPage(#RequestParam(name="error",required = false)String error,
#RequestParam(name="logout",required = false)String logout) {
ModelAndView mv = new ModelAndView("login");
mv.addObject("userClickLoginPage",true);
return mv;
}
#RequestMapping("/perform-logout")
public String logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication);
}
return "redirect:/";
}
}
This class is my main controller
WebSecurityConfig.class
package com.sencerseven.springsecurityauth.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
public static BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Configuration
public static class HomeConfigLogin extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll().and()
.formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("/", true).loginProcessingUrl("/login").and().logout().and().exceptionHandling()
.accessDeniedPage("/").and().csrf();
}
}
}
MyUserDetailService
package com.sencerseven.springsecurityauth.security;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.sencerseven.springsecurityauth.dao.UserDAO;
import com.sencerseven.springsecurityauth.dto.Role;
#Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
#Autowired
private UserDAO userDAO;
#Transactional
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
com.sencerseven.springsecurityauth.dto.User user = userDAO.findByUserName(username);
List<GrantedAuthority> authorities = buildUserAuthority(user.getRole());
return buildUserForAuthentication(user, authorities);
}
private User buildUserForAuthentication(com.sencerseven.springsecurityauth.dto.User user,
List<GrantedAuthority> authorities) {
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<Role> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
for (Role userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
User.class
package com.sencerseven.springsecurityauth.dto;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name = "User")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private boolean enabled;
private String email;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> role;
public User() {
}
public User(String username, String password, boolean enabled, String email, Set<Role> role) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.email = email;
this.role = role;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRole() {
return role;
}
public void setRole(Set<Role> role) {
this.role = role;
}
#Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", enabled=" + enabled
+ ", email=" + email + ", role=" + role + "]";
}
}
Role.class
package com.sencerseven.springsecurityauth.dto;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name = "Role")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String role;
#ManyToMany(mappedBy = "role", fetch = FetchType.LAZY)
private Set<User> user;
public Role() {
}
public Role(String role, Set<User> user) {
this.role = role;
this.user = user;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Set<User> getUser() {
return user;
}
public void setUser(Set<User> user) {
this.user = user;
}
#Override
public String toString() {
return "Role [id=" + id + ", role=" + role + ", user=" + user + "]";
}
}
if you use WebMvcConfigurationSupport and #AuthenticationPrincipal than you must add a AuthenticationPrincipalArgumentResolver:
public class WebMvcConfig extends WebMvcConfigurationSupport {
...
#Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
}
I have the following classes:
ClassA
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import timereport.db.UserBean;
import timereport.utils.JPAUtil;
#Named("classA")
#SessionScoped
public class ClassA implements Serializable {
#Inject
protected UserBean userBean;
public void logout() {
userBean = null;
}
public void login() {
EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
userBean = em.find(UserBean.class, userBean.getUsername());
}
//setter and getter for userBean
}
Here in login() I am doing
EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
userBean = em.find(UserBean.class, userBean.getUsername());
to get the entire UserBean object and this is right. Here comes the problem...
ClassB
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.Date;
import java.util.List;
import java.util.ResourceBundle;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import timereport.db.UserBean;
import timereport.ClassB;
import timereport.utils.JPAUtil;
#Named("classB")
#SessionScoped
public class ClassB implements Serializable {
#Inject private UserBean userBean;
String throughUserBean = userBean.getUsername();
...
}
Here, I don't know why, but I expected to get the username set when the user logs in. And when I call #Inject UserBean or #Inject ClassB I expect they to be from the same session scope and hold the UserBean object that is initialized on login. But both (classB and userBean) return NULL when I refer to them. Am I wrong in my expectations for having these objects set and is there another way to do this?
Here is part of the UserBean class:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.proxiad.timereport.utils.AESEncryptDecryptUtil;
#Named("user")
#SessionScoped
#Entity
#Table(name="t_user")
public class UserBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = -56986575421886097L;
#Id
#Column(name="username")
private String username;
#Column(name="fullname")
private String fullname;
#Column(name="password")
private String password;
#Column(name="email")
private String email;
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn (name="department", referencedColumnName="value")
private ReferenceDataBean department;
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name="role", referencedColumnName="value")
private ReferenceDataBean role;
public UserBean() {}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
try {
this.password = AESEncryptDecryptUtil.encrypt(password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public ReferenceDataBean getDepartment() {
return department;
}
public void setDepartment(ReferenceDataBean department) {
this.department = department;
}
public ReferenceDataBean getRole() {
return role;
}
public void setRole(ReferenceDataBean role) {
this.role = role;
}
#Override
public int hashCode() {
return getUsername().hashCode() + 17 * getEmail().hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj instanceof UserBean) {
UserBean user = (UserBean) obj;
if (getUsername().equals(user.getUsername()) && getEmail().equals(user.getEmail())) {
return true;
}
}
return false;
}
#Override
public String toString() {
return String.format("Username: %s\nEmail: %s\nDepartment:\n%s\nRole:\n%s\n",
getUsername(), getEmail(), getDepartment(), getRole());
}
}
Injection takes place after construction. Injected properties are not available during construction. The earliest point to access injected properties is a #PostConstruct method.
So, replace
#Inject private UserBean userBean;
String throughUserBean = userBean.getUsername();
by
#Inject private UserBean userBean;
String username;
#PostConstruct
public void init() {
username = userBean.getUsername();
}
That #Inject ClassB makes no sense, so I removed it.