Hibernate: Why am I getting an empty json? - java

I have a simple entity class:
#Entity(name = "User")
#Table(name = "users")
#Data
#NoArgsConstructor
public class User {
#Id
#GeneratedValue
private Long id;
private String name;
private Integer age;
private String email;
}
A repository:
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
}
A service:
#Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Iterable<User> findAllUsers() {
return userRepository.findAll();
}
public <U extends User> void saveUser(U user) {
userRepository.save(user);
}
}
A controller:
#RestController
#RequestMapping("api/v1/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
#GetMapping
public Iterable<User> getAllUsers() {
return userService.findAllUsers();
}
#PostMapping
public void addUser(#RequestBody User user) {
userService.saveUser(user);
}
}
And a yaml file:
spring:
datasource:
username: "root"
password: "123123"
url: "jdbc:mysql://localhost:3306/mydbtest"
driverClassName: "com.mysql.jdbc.Driver"
jpa:
hibernate.ddl-auto: update
generate-ddl: true
show-sql: true
I use MYSQL Workbench, where I have a database with one table called users. Sending a get request and trying to get all the objects from the table, I get an empty json. What should I do?

Your code seems ok to me . I think its your IDE issue, you have to enable Lombok annotation processing in your IDE. You can follow this link to enable it.

Could you add #AllArgsConstructor annotation to your entity. I think it might solve your issue. Since currently you only have #NoArgsConstructor and #RequiredArgsConstructor which comes bundled with #Data. And also you don't necessarily need the name paramenter in #Entity

Related

JPA Respository: Data return null when #GetMapping include two required param

Based on my question above, Below is my code.
UserService
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
public List<User> getUserByIdAndEmail(Long id, String email) {
return userRepository.findByIdAndEmail(id, email);
}
}
UserRepository
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
public User findUserByEmail(String email);
public List<User> findByIdAndEmail(long id, String email);
}
UserController
#RestController
public class UserController {
#Autowired
private UserService userService;
#Autowired
private ModelMapper modelMapper;
#GetMapping(path="user/idEmail/{id}/{email}")
public #ResponseBody UserDto getUserByIdAndEmail(#PathVariable long id, #PathVariable String email) {
return modelMapper.map(userService.getUserByIdAndEmail(id, email), UserDto.class);
}
}
User
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Table(name = "idr_user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
}
UserDto
#Data
public class UserDto {
private int id;
private String name;
private String email;
}
And when i enter the correct ID and Email the result is null.
Can I know which part that I missing?
Change
public List<User> findByIdAndEmail(long id, String email);
to
public Optional<User> findByIdAndEmail(long id, String email);
then apply logic if the optional is present.
You shouldn't expect a list in this case as the ID is a primary key, therefor no duplicate. Even if you have duplicated emails, as long as you use id, you won't receive a list.

How to encpyt the password using Springboot?

I have already done user register and login. But I want to encrypt the password when create a profile.
This is my current configuration
MongoDB Connection
spring.data.mongodb.uri= mongodb://127.0.0.1:27017/Student
server.port=8080
Model Class:
#Document
#AllArgsConstructor
#NoArgsConstructor
#Data
public class User {
#Id
#Indexed
private String id;
#Indexed
private String address;
#Indexed
private String name;
#Indexed
private String email;
#Indexed
private String password;
#Indexed
private String role;
}
Repository Class:
public interface userReporsitory extends MongoRepository<User,String> {
Optional<User> findByEmail(String email);
List<User> findAllByRole(String role);
}
Service Class:
#AllArgsConstructor
#Service
public class userService {
private userReporsitory userReporsitory;
public User saveUser(User user){
return userReporsitory.save(user);
}
public User login(User user){
User response = userReporsitory.findByEmail(user.getEmail()).orElseThrow(()->new RuntimeException("User Not Found"));
if(!response.getPassword().equals(user.getPassword())){
throw new RuntimeException("Bad Credincials");
}
return response;
}
public List<User> findAllUsers(){
return userReporsitory.findAllByRole("user");
}
}
Controller Class:
#CrossOrigin
#RestController
#AllArgsConstructor
#RequestMapping("api/v1/user")
public class userController {
private userService userService;
#PostMapping("/create")
public ResponseEntity<User> save(#RequestBody User user){
HttpStatus status = HttpStatus.EXPECTATION_FAILED;
User response = userService.saveUser(user);
if(response != null){
status = HttpStatus.CREATED;
}
return new ResponseEntity<>(response, status);
}
#PostMapping("/login")
public ResponseEntity<User> login(#RequestBody User user){
return new ResponseEntity<>(userService.login(user),HttpStatus.ACCEPTED);
}
#GetMapping("/userList")
public ResponseEntity<List<User>> userList(){
return new ResponseEntity<>(userService.findAllUsers(),HttpStatus.ACCEPTED);
}
}
Use
BCryptPasswordEncoder
Class while saving the Password in DataBase.it will convert the normal text to RandomValue.
Define the BCryptPasswordEncoder In config Class.
#Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
Repository Class :
#Autowired
private PasswordEncoder passwordEncoder;
public User newUserAccount(UserDto accountDto) {
User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
return repository.save(user);
}

HTTP Status 406 in rest api spring boot when getByEmail

I want to search by email but always get "error": "Not Acceptable",
#RestController
#RequestMapping("api/users")
public class UserController {
private final UserService userService;
#Autowired
public UserController(UserService userService) {
this.userService = userService;
}
#GetMapping(value = "/{name:.+}")
public User getUser(#PathVariable String name) {
return userService.getUserByEmail(name);
}
#Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public User getUserByEmail(String email){
User user = userRepository.findByEmail(email).get();
return user;
}
#Repository
public interface UserRepository extends JpaRepository<User,Long> {
Optional<User> findByEmail(#Param("email") String email);
}
even It can fetch from database but when want to return throw error
but throw error
add header application/json header but don't work.
another thing that I can get byId and firstName ,this work correctly
Try adding, value in pathVariable in the controller:
The content in bracket is a regex so it should work.
#GetMapping("/statusByEmail/{email:.+}/")
public String statusByEmail(#PathVariable(value = "email") String email){
//code
}
And from the postman/rest-client
Get http://mywebhook.com/statusByEmail/abc.test#gmail.com/
If this doesn't work try to give the email in URLEncoded format:
The problem might be due to the multiple . in the request
Eg: alireza.ca%40gmail.com
OR
You can set Content-Type: application/x-www-form-urlencoded to automatically do the encoding of the url
Hopefully, this should work.

Spring boot JPA null pointer exception

I am developing an JavaFx application with spring boot,JPA, and H2. I have a user entity when I try to add a new user into the DB it throws NPE in the controller on the button's click action. As it is seen I use only autowire notation. I researched
but findings did not help out. Any help please?
package com.core;
#SpringBootApplication
#Import(SharedSpringConfiguration.class)
public class Runner extends Application {
private ConfigurableApplicationContext context;
public static void main(String[] args) {
launch(args);
}
#Override
public void init() {
context = SpringApplication.run(Runner.class);
}
}
package com.dao;
#Entity
#Table(name = "user")
public class User {
#Id
#Column(name = "id", updatable = false, nullable = false)
private long ID;
#Column(nullable = false)
private String userName;
#Column(nullable = false)
private String userPass;
public User() {
}
public User(long ID, String userName, String userPass) {
this.ID = ID;
this.userName = userName;
this.userPass = userPass;
}
}
package com.service;
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
public UserService() {
}
public void saveUser(User user) {
userRepository.save(user);
}
}
package com.repository;
public interface UserRepository extends CrudRepository<User, Long> {}
package com.controller
#Controller
public class MethodController implements Initializable {
#Autowired
private UserService userService;
#FXML
void methodSave(MouseEvent event) {
userService.saveUser(new User(11, "TestUser", "noPass")); //Throws NPE. Indicates that userService is null. But I autowire the userService.
}
}
I don't know what's in SharedSpringConfiguration, but you probably need #EnableJpaRepositories on one of your configuration classes. #Repository on the CrudRepo should be unnecessary.
Change your SpringBootApplication package from com.core to com
because SpringBootApplication by default will scan only that packages and sub packages.
else
add #ComponentScan annotation in SpringBootApplication and scan the packages.

Repository doesn't save data to H2 in-memory db

Here is my controller method:
// CREATE A USER
#PostMapping("/register")
public String createUser(
#RequestBody User user
) {
if (userService.userExists(user)) {
return "User already exists";
}
userService.saveUser(user);
return "Good job!";
}
UserServiceBean
#Service
public class UserServiceBean {
private UserRepository userRepository;
#Autowired
public UserServiceBean(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User saveUser(User user) {
return userRepository.save(user);
}
public boolean userExists(User user) {
if (userRepository.findByUsername(user.getUsername()) == null) {
return false;
}
return true;
}
And my interface repository:
UserRepository
public interface UserRepository extends CrudRepository<User, Long> {
// TODO: 29.01.17 Create a query to find all todos for logged in user
#Query("select td from User u inner join u.toDoItems td where u = :user")
public Iterable<ToDoItem> findAllToDosForLoggedInUser(#Param("user") User user);
public User findByUsername(String username);
}
And here is my User Entity (getters and setters ommited)
#Entity
#Table (name = "USERS")
public class User extends BaseEntity {
#Column(name = "USERNAME")
private String username;
// TODO: 28.01.17 Find a way to store hashed and salted pws in DB
#Column(name = "PASSWORD")
private String password;
#Column(name = "EMAIL")
private String email;
// user can have many ToDoItems
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<ToDoItem> toDoItems;
// JPA demands empty constructor
public User() {}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
When I shoot JSON at my localhost:8080/register:
{
"username":"ss",
"password":"mkyong.com",
"email":"asdasd#wp.pl"
}
I get response Good job! so it works fine. But when I check my DB at localhost:8080/console it just has Test Table and new User is not added.
I've got my hibernate ddl setup in application.properties set:
# Console to H2 database to check data
spring.h2.console.enabled=true
spring.h2.console.path=/console
spring.jpa.hibernate.ddl-auto=create-drop
So, how do I update my code that it creates table USERS and save created user into that db? I'm going to change my db later on, just using H2 to check if my controllers work fine but it shouldn't matter here.
EDIT:
Here is my RepositoryConfiguration.java:
#Configuration
#EnableAutoConfiguration
#EntityScan(basePackages = {"com.doublemc.domain"})
#EnableJpaRepositories(basePackages = {"com.doublemc.repositories"})
#EnableTransactionManagement
public class RepositoryConfiguration {
}
EDIT2:
When I want to register the same User again (using same JSON) then it gives me "User already exists" resposne so it is already in the db... Why can't I see it then? Maybe I've got H2 somewhere else? Not in the basic /console or different port? How can I check this?
I think you're missing the transactional part of your service. Did you define a transaction manager in your spring context ?
If so, you need to add the annotation #Transactional into your service. For example :
#Service
public class UserServiceBean {
#Transactional
public User saveUser(User user) {
return userRepository.save(user);
}
}
I had to add:
spring.datasource.url=jdbc:h2:~/test
spring.datasource.driver-class-name=org.h2.Driver
to application.properties and it works great now. I just thought I don't need it becasue Spring will auto-configure it for me but apparently it doesn't.

Categories

Resources