Postgres DDL error: 'syntax error at or near "user"' [duplicate] - postgresql

This question already has answers here:
Cannot create a database table named 'user' in PostgreSQL
(5 answers)
Unable to use table named "user" in postgresql hibernate
(6 answers)
Closed 3 years ago.
i am trying to setup spring boot project by using postgres database. my entities are : -
USER
#Entity
public class User implements UserDetails {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id", nullable = false, updatable = false)
private Long id;
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;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JsonIgnore
private Set<UserRole> userRoles = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long 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 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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorites = new HashSet<>();
userRoles.forEach(ur -> authorites.add(new Authority(ur.getRole().getName())));
return authorites;
}
#Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled() {
return enabled;
}
}
ROLE
#Entity
public class Role {
#Id
private int roleId;
private String name;
#OneToMany(mappedBy = "role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private Set<UserRole> userRoles = new HashSet<>();
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
USER_ROLE
#Entity
#Table(name="user_role")
public class UserRole {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long userRoleId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="user_id")
private User user;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="role_id")
private Role role;
public UserRole(){}
public UserRole(User user, Role role) {
this.user = user;
this.role = role;
}
public Long getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(Long userRoleId) {
this.userRoleId = userRoleId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
and my application.properties file looks like:-
server.port=5060
spring.thymeleaf.cache=false
spring.datasource.url=jdbc:postgresql://localhost:5432/pcms
spring.datasource.data-username=sagar
spring.datasource.password=sagar
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
so whenever i run this application. user_role and role tables are created successfully on postgresql database. but user entity throws an exception.
the error says:-
2018-05-07 15:44:15.847 WARN 23619 --- [ restartedMain] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:440) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlStrings(SchemaCreatorImpl.java:424) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.createFromMetadata(SchemaCreatorImpl.java:375) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:166) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:135) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:121) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:155) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:312) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:460) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) [hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.0.1.RELEASE.jar:2.0.1.RELEASE]
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "user"
Position: 108
as you can see the error points on USER entity. but the same entity runs fine when the application is connected to mysql database. i could not quite figure out what is the real error behind it.

User is actually a reserved keyword that Spring JPA doesn't "escape" as-is. However, you can do the keyword escape like so in your entity declaration:
#Entity
#Table(name = "\"User\"")
public class User implements UserDetails { ... }
Spring is likely escaping it for you in your MySql database or taking care of it for you in some other way; not the case for your PostgreSQL DB.

Related

Want to automatically insert current Date in the table When a post Request is made

I have a User Entity and an Order Entity.
One of the field in order entity is date.
Till now i have the user enter the date.
Now i want that at the time post request is made the date is automatically set to the current date and stored in the database.
Tried using #Prepersist annotation But since this is my first API that i am developing using springBoot , I don't really know how to use it.
User Entity
#Entity
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private BigInteger id;
#NotEmpty(message = "Name is compulsory")
#Pattern(regexp="^[A-Za-z]*[A-Za-z-'. ]*[A-Za-z]*$",message = "Name has invalid characters")
private String username;
//#NotEmpty(message = "Phone Number is compulsary")
#Range(min = 6400000000L ,max=9999999999L)
private Long phoneNumber;
#NotEmpty(message = "Address is compulsary")
private String address;
public User(){}
public User(BigInteger id, String username, Long phoneNumber, String address) {
super();
this.id = id;
this.username = username;
this.phoneNumber = phoneNumber;
this.address = address;
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(Long phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Order Entity
#Entity
public class Orders {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private BigInteger id;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
private Date date;
#ManyToOne
private User user;
public Orders(){}
public Orders(BigInteger id, Date date,BigInteger userId) {
super();
this.id = id;
this.date = date;
this.user=new User(userId," ",0000000000L," ");
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Order Controller
#RestController
public class OrdersController {
#Autowired
private OrdersService ordersService;
#ApiOperation(value="Show all orders")
#RequestMapping("/orders")
public Iterable<Orders> getAllOrders()
{
return ordersService.getAllOrders();
}
#ApiOperation(value="Show a particular Order")
#RequestMapping("/orders/{orderId}")
public Orders getOrderById(#PathVariable BigInteger orderId)
{
return ordersService.getOrderById(orderId);
}
#ApiOperation(value="Show all orders of a particular User")
#RequestMapping("/users/{id}/orders")
public List<Orders> getOrders(#PathVariable BigInteger id) {
return ordersService.getOrders(id);
}
#ApiOperation(value="Show an order for a User")
#RequestMapping("/users/{userId}/orders/{id}")
public Orders getOrder(#PathVariable BigInteger id){
return ordersService.getOrder(id);
}
#ApiOperation(value="Adds a new Order")
#RequestMapping(method = RequestMethod.POST,value = "/users/{userId}/orders")
public Orders addOrder(#PathVariable BigInteger userId,#RequestBody Orders orders) {
orders.setUser(new User(userId," ",0000000000L," "));
return ordersService.addOrder(orders);
}
#ApiOperation(value="Alter an Order")
#RequestMapping(method = RequestMethod.PUT, value="/users/{userId}/orders/{id}")
public Orders updateOrder(#RequestBody Orders order,#PathVariable BigInteger id,#PathVariable BigInteger userId)throws Exception {
order.setUser(new User(userId," ",0000000000L," "));
return ordersService.updateOrder(order, id);
}
#ApiOperation(value="Delete an Order")
#RequestMapping(method = RequestMethod.DELETE, value="/orders/{id}")
public void deleteOrder(#PathVariable BigInteger id){
ordersService.deleteOrder(id);
}
}
#PrePersist is a JPA annotation and therefore should work in all compatible persistence frameworks. It indicates a method that should be invoked on particular entity lifecycle event. (Other events are well documented in the Hibernate user guide here).
Add this to your entity:
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date timestamp;
#PrePersist
private void onCreate() {
timestamp = new Date();
}
As for assigning/creating the entity in the controller, it is a good practice to use DTO (data transfer objects) in your controller (#RequestBody OrderDto orderDto) and then use some method to populate a new entity instance with those values. Most common options are
modelmapper
manually
...
Order o = new Order();
o.user = userDao.findById(orderDto.getUserId());
...
// persist o

Spring boot CrudRepository save - exception is org.hibernate.type.SerializationException: could not serialize

Not sure why I have an issue here, but when I save with a CrudRepository with these objects, I get the SerializationException (with no further information). Can someone take a look at my objects and offer me some insight into why they can't serialize? My pom.xml is attached last as well in case that helps somehow. I'm using a Postgres database.
EDIT: The database and now - tables are created, but objects are not creating rows.
The actual CrudRepository interface:
public interface AccountRepository extends CrudRepository<ZanyDishAccount, String> {}
ZanyDishAccount entity:
#Entity
public class ZanyDishAccount {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id; // internal id of the customer account for a Zany Dish subscription
private String status;
#OneToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "company_id")
private Company company;
#OneToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "order_id")
private Order order;
public ZanyDishAccount() {}
public ZanyDishAccount(Company company, Order order) {
this.company = company;
this.order = order;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Override
public String toString()
{
return "ClassPojo [id = "+id+ ", company = " + company + ", status = " + status + "]";
}
}
Company entity:
#Entity
public class Company {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long id;
private String phoneNumber;
private String website;
private String name;
private String uuid;
private String country;
public Company() {}
public Company(String phoneNumber, String website, String name, String uuid, String country) {
this.phoneNumber = phoneNumber;
this.website = website;
this.uuid = uuid;
this.country = country;
}
public String getPhoneNumber ()
{
return phoneNumber;
}
public void setPhoneNumber (String phoneNumber)
{
this.phoneNumber = phoneNumber;
}
public String getWebsite ()
{
return website;
}
public void setWebsite (String website)
{
this.website = website;
}
public String getName ()
{
return name;
}
public void setName (String name)
{
this.name = name;
}
public String getUuid ()
{
return uuid;
}
public void setUuid (String uuid)
{
this.uuid = uuid;
}
public String getCountry ()
{
return country;
}
public void setCountry (String country)
{
this.country = country;
}
#Override
public String toString()
{
return "ClassPojo [phoneNumber = "+phoneNumber+", website = "+website+", name = "+name+", uuid = "+uuid+", country = "+country+"]";
}
}
Order entity:
#Entity
#Table(name = "_order")
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long id;
private String pricingDuration;
private Items[] items;
private String editionCode;
public Order() {}
public Order(String pricingDuration, Items[] items, String editionCode) {
this.pricingDuration = pricingDuration;
this.items = items;
this.editionCode = editionCode;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPricingDuration ()
{
return pricingDuration;
}
public void setPricingDuration (String pricingDuration)
{
this.pricingDuration = pricingDuration;
}
public Items[] getItems ()
{
return items;
}
public void setItems (Items[] items)
{
this.items = items;
}
public String getEditionCode ()
{
return editionCode;
}
public void setEditionCode (String editionCode)
{
this.editionCode = editionCode;
}
#Override
public String toString()
{
return "ClassPojo [pricingDuration = "+pricingDuration+", items = "+items+", editionCode = "+editionCode+"]";
}
}
Thanks for your help!
Mike
Hm, this seems multi-faceted. Let's see if I can help at all. Last thing first...
No tables being created automatically.
I would take a look at this section in Spring's docs for the most basic approach: Initialize a database using Hibernate. For example, spring.jpa.hibernate.ddl-auto: create-drop will drop and re-create tables each time the application runs. Simple and easy for initial dev work. More robust would be leveraging something like Flyway or Liquibase.
Serialization issue
So without logs, and the fact that you have no tables created, the lack of a persistence layer would be the assumed culprit. That said, when you have tables and data, if you do not have a repository for all of the related tables, you'll end up with a StackOverflow error (the serialization becomes circular). For that, you can use #JsonBackReference (child) and #JsonManagedReference (parent). I have been successful using only #JsonBackReference for the child.
Items[]
I'm not sure what Item.class looks like, but that looks like an offensive configuration that I missed the first round.
Change private Items[] items; to private List<Item> items = new ArrayList<Item>();. Annotate with #ElementCollection.
Annotate Item.class with #Embeddable.

The name of the variable is added to the name of the column

I have two entities - Group and UserGroup, they are connected with groupId.
"\" are because postgre is case sensitive and this way we correct this fact.
#Entity
#Table(name = "\"Group\"")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "\"groupId\"")
private int groupId;
#Column(name = "\"groupName\"")
private String groupName;
#OneToMany(mappedBy = "group")
List<Project> projects;
#OneToMany(mappedBy = "group")
private List<UserGroup> members;
public Group(String groupName) {
this.groupName = groupName;
}
public Group() {
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public List<Project> getProjects() {
return projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
public List<UserGroup> getMembers() {
return members;
}
public void setMembers(List<UserGroup> members) {
this.members = members;
}
#Override
public String toString() {
return "Group{" +
"groupId=" + groupId +
", groupName='" + groupName + '\'' +
'}';
}
}
And UserGroup
#Entity
#Table(name = "\"UserGroup\"")
#IdClass(GroupAssociationId.class)
public class UserGroup {
#Id
#Column(name = "\"userId\"")
private int userId;
#Id
#Column(name = "\"groupId\"")
private int groupId;
#ManyToOne
#PrimaryKeyJoinColumn(name = "\"userId\"", referencedColumnName = "\"userId\"")
private User member;
#ManyToOne
#PrimaryKeyJoinColumn(name = "\"groupId\"", referencedColumnName = "\"groupId\"")
private Group group;
#ManyToOne
#JoinColumn(name = "\"accessId\"")
private Access access;
public UserGroup(Group group, User member, Access access) {
this.group = group;
this.member = member;
this.access = access;
}
public UserGroup() {
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public User getMember() {
return member;
}
public void setMember(User member) {
this.member = member;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public Access getAccess() {
return access;
}
public void setAccess(Access access) {
this.access = access;
}
#Override
public String toString() {
return "UserGroup{" +
"userId=" + userId +
", groupId=" + groupId +
", access=" + access.getAccessName() +
'}';
}
}
When I try to create a row in a table UserGroup I get a mistake:
Caused by: org.postgresql.util.PSQLException: ERROR: column "group_groupId" of relation "UserGroup" does not exist
Why? This happens on the string "em.getTransaction().commit(). It is really strange.
In the table UserGroup, a column:
"group_`groupId`"
was generated (because you are using "" to preserve case sensitive.
You can edit in postgres the name for the column (and the foreing key too):
"group_`groupId`" ---> "group_groupId"
JPA is looking for group_groupId.
I've managed to answer this question. The problem was in sequence generation. When generating in embedded database, I don't know why, the generation type sequence doesn't work. Instead I used Identity type and everything started working

JPA Cascade Persist Error

I have a One-to-Many relationship: A ProductCategory can contains many Product. This is the code:
#Entity
public class Product implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private String id;
#Column(name="ProductName")
private String name;
private BigDecimal price;
private String description;
#ManyToOne
#JoinColumn(name="UserId")
private User user;
#ManyToOne
#JoinColumn(name="Category")
private ProductCategory category;
private static final long serialVersionUID = 1L;
public Product() {
super();
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public ProductCategory getCategory() {
return this.category;
}
public void setCategory(ProductCategory category) {
this.category = category;
}
}
#Entity
public class ProductCategory {
#Id
private String categoryName;
#OneToMany(cascade= CascadeType.ALL,mappedBy="category")
private List<Product> products;
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String productName) {
this.categoryName = productName;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
}
This is Servlet code which use the 2 entities:
String name = request.getParameter("name");
BigDecimal price = new BigDecimal(request.getParameter("price"));
String description = request.getParameter("description");
ProductCategory category = new ProductCategory();
category.setCategoryName(request.getParameter("category"));
Product product = new Product();
product.setName(name);
product.setPrice(price);
product.setDescription(description);
product.setCategory(category);
User user = userManager.findUser("Meow");
product.setUser(user);
productManager.createProduct(product); // productManager is an EJB injected by container
And this is the error:
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST
Why does this error happen? I marked the field as "cascade = CascadeType.All"!
You're trying to save a product. And this product is linked to a category. So when JPA saves the product, its category must already exist, or there must be a cascade configured so that persisting the product cascades to persisting its category.
But you don't have such a cascade. What you have is a cascade saying that any operation done on a category cascades to its list of products.

In spring security 3,how to customize my # PreAuthorize annotation?

these days I meet a problem, I can not figure it out,so please help me...
My entity: Utilisateur this is a french word means user
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Utilisateur implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
protected int id;
protected String login;
protected String password;
protected String nom;
protected String prenom;
protected String email;
protected String username;}
#OneToOne(mappedBy="user", cascade={CascadeType.ALL})
private Role role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return login;
}
public void setUsername(String username) {
this.username = username;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
and a Role entity.
In my web app, there is a controller to show for example the information about a student(Etudiant in french)
#EJB(mappedName = "Etudiant.EtudiantFacade")
EtudiantFacade etudiantF;
// Affiche le detail d'un Etudiant (show the infomations of the student)
#RequestMapping(value = "/Etudiant/{idEtudiant}/info")
public ModelAndView detail(#PathVariable String idEtudiant, Model m) {
m.addAttribute("etudiant",
etudiantF.trouver(Integer.parseInt(idEtudiant)));
return new ModelAndView("EtudiantInformation", "null", null);
}
I implemented my own CustomUseDetailService using the entity Utilisateur directly.
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// TODO Auto-generated method stub
System.out.println("!!!!!!!!!!!!!!!!!");
System.out.println(username);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
Utilisateur etudiant = etudiantF.trouverParLogin(username);
return new User(etudiant.getLogin(), etudiant.getPassword(), enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,getAuthorities(etudiant.getRole().getRole()));
}
and my security.xml is below:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/app/Login" access="permitAll"/>
<intercept-url pattern="/app/*" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"/>
<form-login login-page="/app/Login"
authentication-success-handler-ref="authenticationSuccessHandler"/>
<logout logout-url="/app/Logout" logout-success-url="/"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService"/>
</authentication-manager>
Last my question is:
for a student, his id is 1, his username is stu1,to control this student with id 1 can only access his own page information /ProjetName/Student/{studentId}/Info
how do I write the code with #PreAuthorize, I have see the document in form spring, there is example like #PreAuthorize(#contract.name = principal.username), because there is a attribute username in principal, but here,what I need is Id, I use #RequestMapping(value = "/Etudiant/{idEtudiant}/info") to match the student not the username. So how can I solve it? Many thanks... I can not find the tutorial.
You can provide your own implementation for User class (just extend org.springframework.security.core.userdetails.User). Add an identifier field to it. Then set corresponding value in loadUserByUsername method:
#Override
public UserDetails loadUserByUsername(String username)
...
return new CustomUser(etudiant.getId(), etudiant.getLogin(), etudiant.getPassword(), enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,getAuthorities(etudiant.getRole().getRole()));
}
Then you will be able to use it:
#PreAuthorize(#contract.name = principal.id)