I would like to add, edit and get users via an API I have created. I can add users and get all users added via API requests on Postman but I can't get data for a specific user when I request it on Postman as all I get is a null response with a 200 OK status. How can I be able to get a specific user's information using its national Id?
This is how my entity looks like;
public class users {
#Id
private String Id;
#Field("nationalId")
#JsonProperty("nationalId")
private String nationalId;
#Field("userName")
#JsonProperty("userName")
private String userName;
#Field("userEmail")
#JsonProperty("userEmail")
private String userEmail;
#Field("userPin")
#JsonProperty("userPin")
private String userPin;
#Field("userContact")
#JsonProperty("userContact")
private String userContact;
#Field("imageUrl")
#JsonProperty("imageUrl")
private String imageUrl;
#Field("loanLimit")
#JsonProperty("loanLimit")
private String loanLimit;
}
My controller class looks like this;
class Controller {
#Autowired
private user_service User_Service;
#PostMapping("/save_user")
private users save (#RequestBody users Users){return User_Service.save(Users);}
#PutMapping("/update_user")
private users update (#RequestBody users Users){return User_Service.update(Users);}
#GetMapping("/all")
private List<users> getAllusers(){return User_Service.getAllusers();}
#GetMapping("/user/{nationalId}")
private Optional <users> getusers(#PathVariable String nationalId) {return User_Service.getusers(nationalId);}
#DeleteMapping("/delete_user/{nationalId}")
private void deleteUser (#PathVariable String nationalId){User_Service.deleteUser(nationalId);}
}
My user service look like this;
public interface user_service {
users save (users Users);
users update (users Users);
List<users> getAllusers();
Optional<users> getusers(String nationalId);
void deleteUser (String nationalId);
}
You need to specify the name attribute in PathVariable annotation as #PathVariable(name="nationalId")
you need to have a method call like this to get a specific by national id.
Optional<user> getUserByNationalId(String nationalId);
for spring to understand what it is you want to fetch it cant figure it out by just passing in a string.
(And please rename your class User, and not users. The class represents a single user, and also please use camel casing)
Related
I'm trying to get data from MySql Database by custom jpql #query method. I'm not receiving any error, but my list of results is empty.
In console hibernate show results like this:
Hibernate: select flight0_.id as id1_0_, flight0_.arrival_city as arrival_2_0_, flight0_.date_of_departure as date_of_3_0_, flight0_.departure_city as departur4_0_, flight0_.estimated_departure_time as estimate5_0_, flight0_.flight_number as flight_n6_0_, flight0_.operating_airlines as operatin7_0_ from flight flight0_ where flight0_.departure_city=? and flight0_.arrival_city=? and flight0_.date_of_departure=?
I tried to add annotations in model classes like #Column but nothing changed.
Typing lower or uppercase, still nothing. Any suggestions on how to solve this problem?
In this link you can see how my JSP pages, database table and view in the browser looks like https://imgur.com/a/uwBoDmI
#Entity
public class Flight extends AbstractEntity{
private String flightNumber;
private String operatingAirlines;
private String departureCity;
private String arrivalCity;
private Date dateOfDeparture;
private Timestamp estimatedDepartureTime;
Below are getters and setters for those fields.
public interface FlightRepository extends JpaRepository<Flight, Long> {
#Query("from Flight where departureCity=:departureCity and arrivalCity=:arrivalCity and dateOfDeparture=:dateOfDeparture")
List<Flight> findFlights(#Param("departureCity") String from, #Param("arrivalCity") String to,
#Param("dateOfDeparture") Date departureDate);
}
#Controller
public class FlightController {
#Autowired
FlightRepository flightRepository;
#RequestMapping("findFlights")
public String findFlights(#RequestParam("from") String from,#RequestParam("to") String to,
#RequestParam("departureDate") #DateTimeFormat(pattern = "MM-dd-yyyy") Date departureDate, ModelMap modelMap)
{
List<Flight> findFlights = flightRepository.findFlights(from, to, departureDate);
modelMap.addAttribute("flights",findFlights);
for (Flight flightTMP : findFlights) {
System.out.println(flightTMP);
}
return "displayFlights";
}
}
Im making a small application where i can save user details using spring-boot. i created the entities and their corresponding repositories. When ever i make a post request to add a user the id of the user object which is null at the point of saving to the data base.This id is auto generated(Auto Increment) in MySQL. From the POST request i get 3 fields which are username,email,password. The User class contains fields id,username,email,password. I've added the annotations
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Integer id;
for the id field. an the constructors are
public User() { }
public User(String username, String email, String password) {
this.username = username;
this.email = email;
this.password = password;
}
This is the error im getting.
The debugging process
my userService class
#Service
public class UserService implements UserServiceInterface {
#Autowired(required = true)
private UserRepository userrepository;
#Override
public User CreateNewUser(User user) {
return userrepository.save(user);
}
}
my userController class
#RestController
public class UserController {
UserService us = new UserService();
#RequestMapping(value ="/user",method = RequestMethod.POST)
public void RegisterUser(
#RequestParam(value="username") String username,
#RequestParam(value="email") String email,
#RequestParam(value="password") String password){
us.CreateNewUser(new User(username,email,password));
}
}
Any reason why i cant POST to save data to database? how to overcome this?
After digging through the code i found out the error. by creating a new instance of UserService us = new UserService(); this is not managed by Spring (Spring doesn't know about it and cannot inject UserRepository - this causes NullPointerException). there of instead of creting new instace it should extends the UserService class in this example.
I'm having a hard times figuring out how to do update scenario in Play 2 Java
I have
User.java model
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long id;
#Constraints.Required
public String email;
#Constraints.Required
public String fullname;
}
And I want to update it, so in my controller I do
public Result update(Long id) {
ObjectNode result = Json.newObject();
User employee = userService.get(id);
Form<User> userForm = formFactory.form(User.class).fill(employee);
// This won't trigger validation because it uses fill() not bind()
if (userForm.hasError()) {
result.set("message", userForm.errorsAsJson());
return badRequest(result);
}
// do update here
}
Then I try to some different approach like this
public Result update(Long id) {
ObjectNode result = Json.newObject();
User employee = userService.get(id);
Form<User> userForm = formFactory.form(User.class).fill(employee);
userForm = userForm.bindFromRequest();
// This will trigger validation but bindFromRequest will override my fill(employee) before.
if (userForm.hasError()) {
result.set("message", userForm.errorsAsJson());
return badRequest(result);
}
// do update here
}
The bindFromRequest() above will override my fill(employee). I don't want to do that because when in my request I just want to fill fullname and not my email, my email property will trigger its required validation.
So my question is, how can I only update my fullname attribute with the form i fill using existing value and still triggering validation constraints from my model?
Change userForm = userForm.bindFromRequest(); to userForm.bindFromRequest();
I have working code very similar to yours and this is the only difference I've observed.
How to Override spring data repository to select only selected columns when going to pages that are discovered from /api page in spring data rest.
I added findAll as below -
public interface UserRepository extends BaseRepository<User, Integer>, UserRepositoryCustom {
#Query("select u from User u where email = :email and password = :password")
#Cacheable(value = "user-cache", key = "#user.login")
#RestResource(exported = false)
public User findUserByEmailAndPassword(#Param("email") String email, #Param("password") String password);
#RestResource(rel = "byEmail", path = "byEmail")
public User findUserByEmail(#Param("email") String email);
#RestResource(rel = "byPhone", path = "byPhone")
public User findUserByPhone(#Param("phone") String phone);
#Override
#Query("select u.id,u.email,u.phone from User u ")
public Page<User> findAll(Pageable pageable);
}
/api/users is giving an error -
{"cause":null,"message":"PersistentEntity must not be null!"}
I created a UserSummaryProjection class in same package as User
#Projection(name = "summary", types = User.class)
public interface UserSummaryProjection {
Integer getId();
String getEmail();
}
Then, going at /api/users or /users/3?projection=summary gives me desired result without changing the Repository.
Selecting subelements of User and still creating a User is somewhat counterintuitive.
I would create another entity for example UserDetails, that will be mapped by the same table with the same mapping.
public class UserDetails {
private int uid;
private String email;
private String phone;
}
And create a Repository, based on this new Entity.
Assume a model named User:
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
#Constraints.Required
public String password;
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
When I attempt to update an instance of User in my controller:
User user = User.find.where().eq("username", username).findUnique();
if(user != null) {
user.username = "some_new_username";
user.save();
}
no changes seem to be committed. I read somewhere that when you alter a model instance by its property, it does not get dirty and therefore no changes take place. Hence you should use a setter instead. In the documentation of Play Framework it is said that those setters (and getters) are generated automatically, but using user.setUsername(username) gives me a compilation error:
cannot find symbol [symbol: method setUsername(java.lang.String)] [location: class models.User]
Am I missing something?
Have you tried adding custom setters?
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
public void setUsername(String _username) {
username = _username;
}
#Constraints.Required
public String password;
public void setPassword(String _password) {
password = _password;
}
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
As far as I can tell, automatic getter/setter translation is broken in Play2. Your assignment:
user.username = "some_new_username";
should have triggered the function call:
user.setUsername("some_new_username");
This translation seems to be broken in Play 2. Here's my own question on the subject.