I'm using Springboot and I want to create a profile.html page where the User can visualise and edit its informations.
Now, there are 2 tables on my db :
Credentials (login phase)
User (provides user informations
Credentials class :
#Entity
public class Credentials {
public static final String DEFAULT_ROLE = "DEFAULT";
public static final String ADMIN_ROLE = "ADMIN";
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, unique = true)
#NotEmpty
// #Size(min = 5, max = 250)
private String username;
#Column(nullable = false)
#NotEmpty
// #Size(min = 8, max = 20)
private String password;
#Column(nullable = false)
private String role = "DEFAULT";
#OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
private User user;
public Credentials() {
}
public Credentials(String email, String newPassword,long newId) {
this.username=email;
this.password=newPassword;
this.id=newId;
this.user= new User();
}
//some getters and setters
}
And User class :
#Getter
#Setter
#Entity
#Table(name = "users")
public class User {
public User() {}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String name ="";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
In profile page I want to show all User informations (in this case just its name) so I was thinking to get the current user inside ProfileController, add it to Model class and show all informations needed using html.
The problem is that I don't know how to get the current user.
I think the best way to do this is through Id inside Credentials class because it is the foreign key of User table but I don't know how to get this id. Maybe Springboot Authentication class can help?
I was thinking to retrieve, don't know how, current Credentials class with Authentication and use its id to get the linked User (fetchType.EAGER).
This is pseudocode for ProfileController page :
#Controller
public class ProfileController {
#Autowired
UserService us;
#RequestMapping(value="/profile",method = RequestMethod.GET)
public String showProfilePage(Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentUserName = authentication.getName();
Credentials c = getCredentialsFromService() //How I can do this?Is it the right way?
User currentUser = c.getUser();
model.addAttribute("user", currentUser ) ;
return "profile";
}
}
Related
(Not sure if title is fitting for my problem, please correct me if necessary)
I have a controller with a postmapping:
#PostMapping("/user")
ResponseEntity addUser(Users receivedUser, OauthGatewayUser oauthGatewayUser) {
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("POST-Request from user: " + oauthGatewayUser.toString());
logger.info("PostMapping: Received User: " + receivedUser);
userService.addUser(oauthGatewayUser, receivedUser);
return new ResponseEntity(receivedUser, HttpStatus.OK);
}
And I have a users class which can have multiple Islands assigned, so the classes look like this:
#Entity
#Table
public class Users {
#Id
#NonNull
#Column(unique = true)
private String id;
#Column(unique = true)
private String userHandle;
private PrivacyLevel privacyLevelProfile;
private boolean isBlocked;
private Long lastActiveIslandID;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Island> islands = new ArrayList<>();
public Users(String id) {
lastActiveIslandID = 0L;
this.id = id;
privacyLevelProfile = PrivacyLevel.PUBLIC;
}
public Users(String id, String userHandle) {
lastActiveIslandID = 0L;
this.id = id;
this.userHandle = userHandle;
privacyLevelProfile = PrivacyLevel.PUBLIC;
}
public Users() {
}
//Getters and Setters here
}
Island class:
#Entity
#Table
public class Island {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long islandIdOnDevice;
private String name;
private String islandFruit;
public Island(String name, String userID) {
this.name = name;
this.userID = userID;
}
}
public Island() {
}
//Getters and Setters
}
If I now send this as POST-request:
{"id":"baf539b0","islands":[{"islandIdOnDevice":0,"name":"test","fruit":"avocado","userID":"baf539b0"}]}
Then the spring controller logs:
INFO 11916 --- [.83-8083-exec-3] global: POST-Request from user: OauthGatewayUser { id = baf539b0, name = TestUser }
INFO 11916 --- [.83-8083-exec-3] global: PostMapping: Received User: user{id=baf539b0, name='', isBlocked=false, [], last active=null}
What I want is to receive the island as part of the user so I then can attach it in the user service.
The one-to-many annotation specifies an association. It helps spring understand what to do with the collection. But it doesn't 'join' you data in any way when you query it.
Try this:
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn( name = "id", referencedColumnName = "userId")
private List<Island> islands = new ArrayList<>();
I have an entity "User" and an entity "Worker". Now the entity worker has a map "timeMap" in which <LocalTime, User> is stored.
The "User" should "book" a worker with the authentication code at a certain time. The "worker" can then see which "user" has registered at which time and the "user" can see at which time he has registered with which "worker".
UserClass:
#Entity
public class User implements Serializable {
#Id
#Column(name = "user_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String firstname;
private String surename;
private String email;
#Column(unique = true, name = "authCode")
private String authCode;
#SuppressWarnings("unused")
public User() {
}
public User (String firstname, String surename, String email, String authCode) {
this.firstname= firstname;
this.surename= surename;
this.email = email;
this.authCode = authCode;
}
...
}
WorkerClass:
#Entity
public class Worker implements Serializable {
#Id
#GeneratedValue
private long id;
#Column(unique = true, name = "worker_id")
private String username;
private String firstname;
private String surename;
private String email;
private String password;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "users_roles", joinColumns = #JoinColumn(name = "worker_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL)
private Map<LocalTime, User> timeList;
#SuppressWarnings("unused")
public Worker() {
}
public Worker(String firstname, String surename, String email, String password, Set<Role> roles) {
this.firstname = firstname;
this.surename = surename;
this.email = email;
this.password = password;
this.roles = roles;
this.username = createUsername();
}
...
What is the best way to write a method in the repository(or later in my service class) to search all workers with a "user" and return a Map<LocalTime, Worker> containing all booked times and the worker, which the user has booked?
e.g.
The user enters his Auth Code. This will search the UserRepository for the User Entity.
This should now be used to search in the WorkerRepository for all map entries of all Worker Entites for the user and his time.
e.g.
Map of Worker1-> (5:00, User1; 5:10, User2; 5:20, User3)
Map of Worker2-> (5:20, User1; ....)
Result for User1:
User1 --> (5:00, Worker1; 5:20, Worker2)
This should work (if your project is running on Java / JDK version 1.8+). I wasn't able to test it though. I hope this works for you:
User userToUseAsFilter = /*<The user reference you want to search for>*/;
Map<LocalTime, Worker> map =
workerList.stream()
.flatMap(w -> w.getTimeList().entrySet().stream()
.map(ue -> new EntryHolder(w, ue.getKey(), ue.getValue())))
.filter(eh -> Objects.equals(eh.user, userToUseAsFilter))
.collect(Collectors.toMap(
eh -> eh.time,
eh -> eh.worker,
(w1, w2) -> w1 // Cannot combine two workers into one instance, therefore just ignore worker 2 if they both have the same local time
));
You also need the following class to temporarly hold a few values:
public class EntryHolder {
public final Worker worker;
public final LocalTime time;
public final User user;
public EntryHolder(Worker worker, LocalTime time, User user) {
this.worker = worker;
this.time = time;
this.user = user;
}
}
You should also add an equals method inside of your user class, in oder to actually find the user inside the map (I used the generate feature in IntelliJ to generate these two methods automatically):
public class User implements Serializable {
... // All of your fields are here
// Auto generated using IntelliJ:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id && Objects.equals(firstname, user.firstname) && Objects.equals(surename,
user.surename) && Objects
.equals(email, user.email) && Objects.equals(authCode, user.authCode);
}
// Auto generated using IntelliJ:
#Override
public int hashCode() {
return Objects.hash(id, firstname, surename, email, authCode);
}
}
I trying to make relation between phonebook and user through jpa, when the current logged in user creates a contact the foreign key of user in table phonebook remains null. I checked couple of question here but it did'not work for me.
Phonebook
#Entity
#Table(name = "Phonebook")
public class Phonebook {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "phonebook_id")
private Long id;
#Column(name = "phone", length = 15, nullable = false)
private String phoneNumber;
#Column(name = "firstname", length = 50, nullable = false)
private String firstName;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
//getters and setters
User
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private Long id;
#Column(name = "email")
private String email;
#Column(name = "password")
#Length(min = 5, message = "*Your password must have at least 5 characters")
#org.springframework.data.annotation.Transient
private String password;
#OneToMany(mappedBy = "user")
private List<Phonebook> phonebooks;
//getters and setters
PhonebookController
#RequestMapping(value = {"/home/phonebook"}, method = RequestMethod.GET)
public String showPage(Model model, #RequestParam(defaultValue = "0") int page){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
model.addAttribute("data",phonebookRepository.findAllByUserId(user.getId(),PageRequest.of(page,10)));
model.addAttribute("currentPage",page);
return "/home/phonebook";
}
#PostMapping("/home/phonebook/save")
public String save (Phonebook p){
phonebookRepository.save(p);
return "redirect:/home/phonebook";
}
PhonebookRepository
#Repository("phonebookRepository")
public interface PhonebookRepository extends JpaRepository<Phonebook,Integer> {
List<Phonebook> findAllByUserId(Long id, Pageable pageable);
}
what You have to do the first create a user object and set the id and then persist the phone book.
You must persist PhoneBook together with your User.
User u = new User();
// Set properties for your User...
PhoneBook p = new PhoneBook();
// Set properties for your phonebook...
// Store phone book to user:
u.setPhoneBook(Collections.singletonList(p));
userRepository.save(p);
i am trying to get the roles from a user in our ldap system.
First of all, my ldap user entry and role entry:
#Data
#Entry(objectClasses = {"inetOrgPerson", "top"}, base = "ou=people"
public class LdapUserEntry {
#Id
private Name id;
#DnAttribute(value = "uid")
private String username;
#Attribute(name = "cn")
private String cn;
#Attribute(name = "userPassword")
private String password;
#DnAttribute(value = "ou")
#Transient
private String group;
}
Role Entry class:
#Data
#Entry(objectClasses = {"groupOfUniqueNames", "top"}, base = "ourBase")
public class LdapRoleEntry {
#Id
private Name dn;
#DnAttribute("cn")
private String name;
#Attribute(name = "uniqueMember")
#Transient
private List<String> members;
}
For our authorization and authentication, i need to get the roles from the ldap, before the user gets logged.
EDIT: My Repos looks like:
public interface LdapUserRepository extends LdapRepository<LdapUserEntry> {
LdapUserEntry findByUsername(String username);
}
public interface LdapRoleRepository extends LdapRepository<LdapRoleEntry> {
}
Thank you!
While saving some data from the form I also need to add FK to the Record table. FK is User.Id.
I know how to save data from the input field on the form, but how can I set FK (int value) to this:
#ManyToOne
#JoinColumn(name = "id")
#Cascade({CascadeType.ALL})
private User user;
Is there some way to retrieve object which relates to logged user and make something like this: record.setUser(user)?
I've googled it but I didn't manage to find how to achive this.
This is my entity class.
#Entity
public class Record implements java.io.Serializable{
#Id
#GeneratedValue
private int recordId;
private String recordName;
private String recordComment;
private Date recordDate;
private Integer price;
#ManyToOne
#JoinColumn(name = "userId", insertable = true, updatable = false)
#Cascade({CascadeType.ALL})
private User user;
......
}
#Entity
#Table(name = "system_user")
public class User implements java.io.Serializable{
#Id
#GeneratedValue
private int userId;
#NotEmpty
#Email
private String email;
#Size(min=2, max=30)
private String name;
private String enabled;
#NotEmpty
private String password;
private String confirmPassword;
#Enumerated(EnumType.STRING)
#Column(name = "user_role")
private Role role;
#OneToMany(fetch = FetchType.EAGER,mappedBy = "user", orphanRemoval=true)
#Cascade({CascadeType.ALL})
private List<Record> records;
public void addToRecord(Record record) {
record.setUser(this);
this.records.add(record);
}
....
}
This is how I save data to DB:
#RequestMapping(value = "/protected/add", method = RequestMethod.POST)
public String addCost (#ModelAttribute("record") Record record,HttpSession session){
User user = userManager.getUserObject(userManager.getUserId(session.getAttribute("currentUser").toString()));
user.addToRecord(record);
recordService.addRecord(record);
return "redirect:/protected/purse";
}
DAO:
public void addRecord(Record record) {
sessionFactory.getCurrentSession().save(record);
}
UPDATE: problem was partially solved, code above works fine for me.
You also need to create User object and set the user object in a Record object using the below code
record.setUser(userObj);
and user foreign key will be automatically saved in database.