spring data mongodb MongoRepository.save(T entity) method not working? - spring

The code is listed below:
#Document
#XmlRootElement
public class User {
#Indexed(unique=true)
private String username;
private String firstName;
private String lastName;
private String password;
...... omit setters and getters
}
public interface UserRepo extends MongoRepository<User, String>{
}
public User update(User user) {
User existingUser = userRepo.findByUsername(user.getUsername());
if (existingUser == null) {
return null;
}
existingUser.setFirstName(user.getFirstName());
existingUser.setLastName(user.getLastName());
return userRepo.save(existingUser);
}
when update method invoked, the finds the user based on username and finishes without any exceptions, the returned User obj has all updated value but the underlying mongodb document is not changed! Can anyone help? Thanks.

you need an Id field with #Id annotation

Related

How can Ifetch Users conversation list where user A has conversations with User B,C And D?

I'm using Spring Data JPA but I'm stuck on how to create a query based on who a user has chat history with.
I have the two objects of which Message is an entity while Chat-Message is not.
You can take a look from both classes and guide me on how I can create a spring data JPA query that queries certain users conversations with other users:
#Entity
public class Message {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long id;
String message;
#ManyToOne
#JoinColumn(name="fromUser",nullable=false)
private User fromUser;
#ManyToOne
#JoinColumn(name="toUser",nullable=false)
private User toUser;
public Message() { }
public Message(User fromUser, User toUser, String message) {
this.fromUser=fromUser;
this.toUser=toUser;
this.message=message;
}
public Long getId() {
return id;
}
// getters and setters
}
public class ChatMessage {
Long id;
String message;
String sender;
String username;
Long senderId;
public ChatMessage() { }
// getters and setters
public ChatMessage(Message m, Boolean isReply) {
this.sender = m.getFromUser().getFirstname() + " " + m.getFromUser().getLastname();
this.message = m.getMessage();
this.senderId = m.getFromUser().getId();
this.id = m.getId();
}
}
My possible endpoint:
#RequestMapping(value="/conversations",produces = "application/json")
#ResponseBody
public List<Message> myMessages(Principal principal){
String thisUser=principal.getName();
User user=userServiceImpl.findByUsername(thisUser);
// List<Message>messages=messageServiceImpl.finddAll();
List<Message> messages=messageServiceImpl.fetchMessages(user.getId());
return messages;
}
Note that Chat-Message is just an object class for carrying WebSocket messages. My Message Repo:
public interface MessageRepository extends JpaRepository<Message,Long>{
}
Image: [1]: https://i.stack.imgur.com/hVbP3.png
It's not really clear what exactly you need here, and what messageServiceImpl does, for instance. But, maybe this will be useful:
public interface MessageRepository extends JpaRepository<Message, Long> {
// if we get all messages your user sent or received - would it be
// what you mean here a "conversation" ?
List<Message> findByFromUserIdOrToUserId(Long id);
// or you can use #Query to achieve the same
#Query("select m from Message m where m.fromUser.id = :id or m.toUser.id = :id")
List<User> findMessagesForUser(Long id);
}
You can also find more details of how to create queries using Spring Data in their official docs.

Spring boot application I can not get data from oracle database it returns [] in postman

Spring boot application I can not get data from oracle database it returns []. In postman, it returns other requests e.g home method in controller class returns correctly. also, the table created by model class the problem is getting data from the table.
Here is the postman result:
I get this in console:
Model class
#Entity // This tells Hibernate to make a table out of this class
public class Userr {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
//Controller Class
#RestController
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#PostMapping(path="/add") // Map ONLY POST Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
Userr n = new Userr();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<Userr> getAllUsers() {
// This returns a JSON or XML with the users
//
return userRepository.findAll();
}
#GetMapping(path="/al")
public List<Userr> printPersonInfo() {
List<Userr> list = new ArrayList<>();
userRepository.findAll().forEach(list::add);
return list;
}
#RequestMapping("/user")
public String home(){
return "PPPPPP";
}
}
//Repository Class
public interface UserRepository extends CrudRepository<Userr, Integer> {
}
Add #Repository annotation to your UserRepository. It will help with your issue.

Object is not an instance of a persistable class warning with Spring boot and Neo4j

I have a pretty straightforward class called User which is supposed to create user objects containing user information and login details.
package com.example.domain;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import java.util.HashSet;
import java.util.Set;
#NodeEntity
public class User {
public User() {}
#GraphId
private Long id;
private String username;
private String password;
private String name;
private String email;
private String Role;
#Relationship(type="BELONGS_TO", direction = Relationship.INCOMING)
Set<Item> items = new HashSet<>();
public User(String name, String username, String password, String email) {
this.name = name;
this.username = username;
this.password = password;
this.email = email;
}
// Getters and setters below for private fields...
}
The controller creating the object looks like this:
#RequestMapping(value = "/register",method = RequestMethod.POST)
public String register(Model model,
#ModelAttribute(value="name") String name,
#ModelAttribute(value="username") String username,
#ModelAttribute(value="email") String email,
#ModelAttribute(value="password") String password,
#ModelAttribute(value="confirmPassword") String confirmPassword) {
if(!password.equals(confirmPassword)) {
model.addAttribute("error", true);
return "register";
}
User userEntity=new User(name,username,password,email);
userManagementService.save(userEntity); //<------The object is created but the error occures during persistance
return "login";
}
and my user management service looks like this:
public interface UserManagementService {
List<User> listAll();
User save(User user);
User findUser(String username);
}
What makes the User class, not an instance of a persistable class. What are the characteristics of a persistable class and how can I make User a persistable class?
Have you configured the OGM somewhere? Either in a Java configuration or in a ogm.properties file? You'll need to specify the driver type and tell the SessionFactory where to look for your domain objects.
OGM config reference: https://neo4j.com/docs/ogm-manual/2.1/reference/#reference:configuration
SessionFactory config reference: https://neo4j.com/docs/ogm-manual/2.1/reference/#reference:connecting:session-factory

why I can't use string as id

I am trying to create a user model with a CrudRepository:
#Entity
public class User {
#Id
#GeneratedValue
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
public interface UserRepository extends CrudRepository<User, String> {
}
However I got an 500 error every time I call findOne():
#Controller
public class UserController {
#Autowired
private UserRepository users;
#Override
#RequestMapping(value="/register", method=RequestMethod.POST)
public #ResponseBody User register(#RequestBody User userToRegister) {
String username = userToRegister.getUsername();
User user = users.findOne(id);
if (user != null) {
return null;
}
User registeredUser = users.save(userToRegister);
return registeredUser;
}
}
However if I just switch to an long type id instead of username itself then everything works. I think it's common to use string as id. So how to make this work?
I use the embedded hsql database. I didn't wrote any sql code.
The problem is that String username; is annotated with both #Id and #GeneratedValue. #Id means that is should be a primary key, fine it can be a String. But #GeneratedValue means that you want the system to automatically generate a new key when you create a new record. That's easy when the primary key is integer, all databases have a notion of sequence (even if the syntax is not always the same). But if you want String automatically generated keys, you will have do define your own custom generator.
Or if you have no reason for the #GeneratedValue annotation, simply remove it as suggested by Bohuslav Burghardt
Use column annotation like below by putting nullable False.
#Id
#GeneratedValue
#Column(name = "username", nullable = false)
private String username;

Returning returned model object to json String using spring data jpa with hibernate

I am using spring data jpa with hibernate
This is my dao interface
#Repository
public interface IUserDAO extends JpaRepository<User, Integer>{
User findByUsername( final String username );
}
This is my User class
Entity
#Table(name="USER")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="ID", nullable = false)
private int id;
#Column(name="USERNAME", nullable = false)
private String username;
#Column(name="NAME", nullable = false)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is my UserImplClass
This is my UserImplClass{
#Autowired
private IUserDAO iUserDAO;
public String findUserByUserName(String username) {
User user =iUserDAO.findByUsername(username);
Convert user to json object from framework level automatically
// i can add my one implemenation of converting user to json here ,but i want to achieve it from framework so that my code is not scattered on every service level
return "jsonStringOfUserObject"
}
Is it possible with spring data jpa with hibernate so that i do not have to write code for converting java object to json string in every service level?
I am using spring ,therefore i want to achieve it from spring .
You have two options to do what you want:
1) If you plan on returning this Object as an HTTP Response, and you use Spring MVC with Controllers you can annotate your controller method as follows:
public #ResponseBody User getUser(){
return userImplClass.findUserByUserName("yourusername");
}
2) If you want the UserImplClass itself to return a JSON String (which I do't recommend, but I leave you the decision), you can use Jackson Object Mapper to do it for you (you can inject it if you declare it as a bean on your configuration xml, or create a new instance of it, I personally prefer injecting it with #Autowired)
public String findUserByUserName(String username) {
User user =iUserDAO.findByUsername(username);
ObjectMapper mapper = new ObjectMapper(); // no need to do this if you inject via #Autowired
return mapper.writeValueAsString(user);
}

Resources