spring boot CrudRepository query passing object mysql - java

I have the following code:
public interface UserRepository extends CrudRepository<User, Integer> {
#Modifying
#Transactional
#Query(value = "INSERT INTO users(email, password, name) VALUES (?,?,?)", nativeQuery = true)
void insertUserToUsers(String email, String password, String name);
}
I don't want to pass the values, i want to pass a user object like this:
void insertUserToUsers(User user);

Try this
public interface UserRepository extends CrudRepository<User, Integer> {
#Modifying
#Transactional
#Query(value = "INSERT INTO users(email, password, name) VALUES (:#{#user.email},:#{#user.firstname},:#{#user.name})", nativeQuery = true)
void insertUserToUsers(#Param("user") User user);
}

Try this code,
#Modifying
#Transactional
#Query(value = "INSERT INTO users(email, password, name) VALUES (?,?,?)", nativeQuery = true)
void insertUserToUsers(String email, String password, String name);
default void insertUserToUsers(User user) {
return insertUserToUsers(user.getEmail(), user.getPassword(), user.getName());
}

Where you use your UserRepository you can use the default method to save user:
ex:
#Service
public class MyService{
#Autowired
private UserRepository userRepository ;
public void example(User user){
userRepository.save(user)
}
}
Because CrudRepository give us some default methods , you can check here

Related

How to avoid changing object in cache before saving Spring Cache

I want to show right away with an example. There is such a repository:
#Repository
public interface UserRepository extends JpaRepository<User, Integer> {
String USER_CACHE = "users";
#Override
#CachePut(value = USER_CACHE, key = "#user.email", unless = "#result == null")
<S extends User> S save(S user);
#Override
#CacheEvict(value = USER_CACHE, key = "#user.email")
void delete(User user);
#Cacheable(value = USER_CACHE, key = "#email", unless = "#result == null")
User findByEmailIgnoreCase(String email);
}
And there is such a service that saves the user's changes and sends a confirmation code to the mail:
#Service
public class UserServiceImpl implements UserService, UserDetailsService {
private final UserRepository userRepository;
#Override
public User getUserByEmail(String email) {
return userRepository.findByEmailIgnoreCase(email);
}
#Override
#Transactional(isolation = Isolation.SERIALIZABLE)
public void createAppUser(RegistrationAppRequestDto registrationRequest) throws EmailSendingException {
User user = getUserByEmail(registrationRequest.getEmail());
user.setPassword(registrationRequest.getPassword());
user.setApp(true);
user.setActivated(false);
user.setActivationCode(UUID.randomUUID().toString());
user.setLastVisit(LocalDateTime.now());
if (Strings.isEmpty(user.getImg())) {
user.setImg(DEFAULT_IMG);
}
mailSender.sendWelcomeMessage(user);
userRepository.save(user);
}
}
And the problem is that in case of an error (For example, when sending a message to the mail), the changes that were made with this user will remain in the cache, and these changes will not get into the database (which is correct). Is there any practice of working with such a case? Alternatively, i can use object cloning, but I think this is a bad practice. I will be grateful for any help.

JPA - check if the user exists in the database by name?

i'm triying user this code
public interface UserRepository extends CrudRepository<Usuario, Long> {
#Query("select p from User p where name = ?1")
public boolean findExistByname(String name);
#Query("select p from User p where email = ?1")
public boolean findExistByEmail(String email);
}
to check if the user in the database exists, but when not, it returns null and an error, I just don't know how to do this
You need to select a boolean value.
#Query("select count(p) = 1 from User p where name = ?1")
public boolean findExistByname(String name);
Try following code:
#Repository
public interface UserRepository extends CrudRepository<UserEntity, Long> {
Optional<UserEntity> findByName(final String name);
}
and then check whether user exists:
userRepository.findByName("username goes here")
.orElseThrow(() -> new SecurityException("User not found in database"));
or:
userRepository.findByName("username goes here").isPresent()

Special select query is not working in my spring boot application

Repository Class:
#Repository // This my architecture repository class.
public class UserRepositoryImp implements UserRepository {
private EntityManager entityManager;
#Autowired
public UserRepositoryImp(EntityManager entityManager) {
this.entityManager = entityManager;
}
private static final String MY_SQL_COUNT_EMAIL =
"SELECT count(e) FROM User e WHERE e.email=:email "; // This is hibernate query.
#Override
public Integer getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
TypedQuery<Integer> query = session.createQuery(MY_SQL_COUNT_EMAIL, null);
query.setParameter("email", email); // This is return count in database check database
// .. if you email this database passing already exist this email but your count zero created new email.
return query.executeUpdate();
}
}
Service Class:
#Service
#Transactional
public class UserServiceImp implements UserService {
#Autowired
UserRepository userRepository;
#Override
public User validateUser(String email, String password) throws EtAuthException {
return null;
}
#Override
public User registerUser(User user) throws EtAuthException {
Pattern pattern = Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2, 6} $ "); // This regex.
if (pattern.matcher(user.getEmail()).matches()) {
throw new EtAuthException("Invalid email format"); // This is check email regex.
}
Integer count = userRepository.getCountByEmail(user.getEmail()); // This is my method
// .. count email in database and repository methods
if (count > 0) {
throw new EtAuthException("Email already in use");
}
Integer userId = userRepository.create(user);
return userRepository.findById(userId);
}
}
Postman Error:
Cannot invoke "java.lang.Class.isAssignableFrom(java.lang.Class)"
because "resultClass" is null"
Problem:
My problem is actually. I want to write a query to hibernated but for some reason it doesn't work. For such operations in spring boot, ie typing a query, for example polling email, put delete add and updated, how do I do it? I need to query me. I can't solve this problem.
You are calling executeUpdate() for a select query. Try using getSingleResult() instead.
#Override
public long getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = session.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}
OR
#Override
public long getCountByEmail(String email) {
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = entityManager.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}

How to delete record in MongoDB using Spring Data

I want to delete an record based on Id in Spring.
but in database id value is object
EX:-
id: Object(34562341112313)
How to delete this record in Spring?
You do like this:
public void deleteRecord() {
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
Query searchQuery = new Query(Criteria.where("id").is(34562341112313));
mongoOperation.remove(searchQuery, Your_entity_class.class);
logger.info("Delete success");
}
This is my realistic example:
/**
* Delete by condition(s).
*/
public void deleteJob() {
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
Query searchQuery = new Query(Criteria.where("company").is("DCV"));
mongoOperation.remove(searchQuery, Job.class);
logger.info("Đã xóa các công việc đăng bởi DCV.");
}
Source: https://github.com/SmartJobVN/MongoDB_SpringDataMongo/blob/master/src/main/java/vn/smartJob/jobs/MongoSpringJavaConfigApplication.java#L132
Reference: http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/
You should delete it like this:
#Repository
public class AppDaoClass{
#Autowired
MongoTemplate mongoTemplate;
#Override
public void deleteSomething(String somethingId) {
mongoTemplate.remove(Query.query(Criteria.where("somethingId").is(somethingId)), Ticket.class);
}
}
The first "somethingId" is the name you gave it in your model, and the second somethingId is for the Parametar you are giving in you method.
And your Domain Model:
#Document
public class Model {
#Id
private String somethingId;
private String someName;
private String someOtherName;
}
Be sure to user proper annotations for your classes #Document and #Repository. And add an #Id annotation to your ID field.
Hope this helps.
This is the way you can delete records in spring data mongoDB using MongoTemplate
WriteResult writeResult=mongoTemplate.remove(query,"collection_name");
OR
WriteResult writeResult=mongoTemplate.remove(query,EntityClassName.class);
You can also use repository Pattern
#Document(collection = "user")
public class User {
#Id
private String id;
private String username;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
#Repository
public interface UserRepository extend MongoRepository<User, String>{
public void delete(String id);
public void delete(User user);
public void deleteByUsername(String username);
}
you can use these method anywhere to delete records also u can write your custom methods
#Query(value = "{'_id' : ?0}", delete = true)
void deleteById(String id);

java method returning null value

In doing a project using Spring MVC. The basic is: when a student signs up, his data will be stored in the database table and the password will be sent to the students mail address.
So I have:
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String dosignup(#Valid #ModelAttribute("student") Student student, HttpServletRequest request,
HttpServletResponse response, BindingResult result) {
studentService.addNewStudent(student.getName(),
student.getUsername(), student.getEmail(), student.getPassword());
studentService.sendEmail(student);
}
StudentDao interface is:
public interface StudentDao {
public void saveStudent(Student student);
public void fetchinfo(Student student);
}
fetchinfo implementation in StudentDaoImpl is:
public void fetchinfo(Student student) {
String hql = "select password from student where email = :email";
sessionFactory.getCurrentSession().createSQLQuery(hql)
.setParameter("email", student.getEmail()).uniqueResult();
}
StudentService interface is:
public interface StudentService {
Student addNewStudent(String name, String username, String email, String password);
void sendEmail(Student student);
Student fetchinfo(String email);
}
and StudentServiceImpl is:
public User fetchinfo(String email) {
Student student = new Student(email);
studentDao.fetchinfo(student);
return student;
}
public void sendEmail(Student student) {
mailService.accountActivation(student);
}
Now, the problem is: a mail is sent to the students mail address, but the password is null. Can someone explain why this happens?
In StudentDaoImpl you are not setting the password property from the db query result. Rewrite relevant line as:
student.setPassword(sessionFactory.getCurrentSession().createSQLQuery(hql)
.setParameter("email", student.getEmail()).uniqueResult());
Update
While we are in Hibernate, by convention Student entity should have getters and setters for each property. Then I would rewrite StudentDaoImpl as:
public void fetchinfo(String email) {
String hql = "select s from student s where s.email = :email";
return (Student)sessionFactory.getCurrentSession().createSQLQuery(hql)
.setParameter("email", email).uniqueResult();
}
..and call it with student = studentDao.fetchinfo(email); (of course naming of methods should change).

Categories