I am trying to update some user information by passing List of User-Ids as parameter
i want to update isActive field of User fo which i am passing the user ids.
Below is my controller
#PutMapping
#ResponseStatus(HttpStatus.OK)
#RequestMapping("/UserUpdate")
public ResponseEntity<?> updateUsers(List<Long> userIds) {
**userService.updateUsers(userIds);**
return ResponseEntity.ok(200);
}
updateUsers() is a method in my Service where i have to write the logic
I tried something like below but it's not working
public void updateUsers(List<Long> userIds) {
List<Users> userList= userRepository.findAll();
for (Long i : userIds) {
for ( Users user : userList)
{
if(userRepository.findById(i) != null)
{
user.setIsActive(9L);
user.setUserName("Update Test");
}
my dto
public class UserDto {
private List<Users> userList;
private String appName="Users Project";
// getters and setters removed for brevity
And my Users entity class
#Entity
#Table(name="USERS")
public class Users {
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
#Column(name="NAME")
private String userName;
#Column(name="ACTIVE")
private Long isActive;
// getters and setters removed for brevity
Alternatively you can use the following code
#Modifying
#Query("update Users u set u.isActive = ?1, u.userName = ?2 where u.userId in ?3")
void updateUsers(Long isActive, String userName, List<Long> userId);
Add this code in your userRepository and use the method.
public void updateUsers(List<Long> userIds) {
for (Long i : userIds) {
User user = userRepository.findById(i);
if(user != null){
user.setIsActive(9L);
user.setUserName("Update Test");
// call your update method here (this is not stated in your code)
}
}
}
Related
I have a User, and the user has Expenses. In expenses table I want to have the expense id, the user who made the expense and the amount of expense. In the user table I want user id, his username, his current balance and list of all expenses he's made.
I want to join those 2, but I don't know how to correctly reference user, therefore user form Expense class is always null.
First, I send post request to create a user:
{
"username":"abcd",
"balance":"100"
}
then I want to create an expense, but here I'm not sure how to correctly send a User:
{
"username":"abcd",
"id":"1",
"balance":"100",
"amount":"20"
}
and this doesn't work, then I tried like this:
{
"User":{
"username":"abcd",
"id":"1",
"balance":"100"
},
"amount":"20"
}
and that didn't work either.
This is the User class:
#Entity
#Table(name = "Users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Username is mandatory")
private String username;
private Double balance = 0.0;
#OneToMany(mappedBy = "user")
private List<Expense> expenses;
...
I removed getters and setters from here.
Here is the Expense class:
#Entity
#Table(name = "Expenses")
public class Expense {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
private Double amount;
...
For saving the expense I use .save() from JpaRepository<Expense, Long> and for retrieveing everyting I use .findAll().
The result is always the same: get for all expenses gives
{
"id": 1,
"user": null,
"amount": 20
}
and get for all users gives
{
"id": 1,
"username": "abcd",
"balance": 100,
"expenses": []
}
Now I'm not sure whether I'm sending the requests the wrong way or joining the tables the wrong way or both.
EDIT: here is ExpenseController:
#RestController
public class ExpenseController {
#Autowired
IExpenseService expenseService;
#GetMapping("/expenses")
public List<Expense> findExpenses() {
return expenseService.findAll();
}
#PostMapping("/expenses")
public void createNewExpense(#RequestBody Expense expense) {
expenseService.createNewExpense(expense);
}
}
createNewUser(...) from ExpenseService
#Override
public void createNewExpense(Expense expense) {
repository.save(expense);
}
and ExpenseRepository:
#Repository
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
}
UserController:
#RestController
public class UserController {
#Autowired
IUserService userService;
#GetMapping("/users")
public List<User> findUsers() {
return userService.findAll();
}
#GetMapping("/users/{id}")
public User findUserById(#PathVariable Long id) {
return userService.findById(id);
}
#PostMapping("/users")
public ResponseEntity<Object> createUser(#RequestBody User user) {
if (userService.checkIfUsernameIsTaken(user)) {
Map<String, Object> response = new HashMap<>();
response.put("status", HttpStatus.NOT_ACCEPTABLE);
response.put("errors", "Username is already taken");
response.put("timestamp", new Date());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
} else {
userService.createNewUser(user);
User currentUser = userService.findById(userService.findByUsername(user.getUsername()));
Map<String, Object> response = new HashMap<>();
response.put("id", currentUser.getId());
response.put("username", currentUser.getUsername());
response.put("balance", currentUser.getBalance());
response.put("expenses", currentUser.getExpenses());
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
#DeleteMapping("/users/{id}")
public void deleteUser(#PathVariable Long id) {
userService.deleteUser(id);
}
#PutMapping("/users/{id}/{balance}")
public void updateBalance(#PathVariable Long id, #PathVariable Double balance) {
userService.updateBalance(id, balance);
}
}
the rest of the User model is the same as the Expense model.
Try to send post request with this payload (field 'user' begins with a small letter), and i think the 'id' field in user object should be enough
{
"user":{
"username":"abcd",
"id":"1",
"balance":"100"
},
"amount":"20"
}
EDIT: Also you need to add #JsonIgnoreProperties("expenses") to your Expense entity to prevent jackson from recursive reading json
#Entity
#Table(name = "Expenses")
public class Expense {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#JsonIgnoreProperties("expenses")
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
private Double amount;
.....
I want to use Objectify to query Google Cloud Datastore. What is an appropriate way to find a record based on a known key-value pair? The record is in the database, I verified this by Google's Datastore viewer.
Here is my method stub, which triggers the NotFoundException:
#ApiMethod(name="getUser")
public User getUser() throws NotFoundException {
String filterKey = "googleId";
String filterVal = "jochen.bauer#gmail.com";
User user = OfyService.ofy().load().type(User.class).filter(filterKey, filterVal).first().now();
if (user == null) {
throw new NotFoundException("User Record does not exist");
}
return user;
}
Here is the User class:
#Entity
public class User {
#Id
Long id;
private HealthVault healthVault;
private String googleId;
public User(String googleId){
this.googleId = googleId;
this.healthVault = new HealthVault();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public HealthVault getHealthVault() {
return healthVault;
}
public void setHealthVault(HealthVault healthVault) {
this.healthVault = healthVault;
}
public String getGoogleId() {
return googleId;
}
public void setGoogleId(String googleId) {
this.googleId = googleId;
}
}
I think it fails because of transaction. You need to make a transctionless call like:
User user = OfyService.ofy().transactionless().load().type(User.class).filter(filterKey, filterVal).first().now();
More info about transactions on App Engine:
https://cloud.google.com/appengine/docs/java/datastore/transactions
https://github.com/objectify/objectify/wiki/Transactions
EDIT
Your object needs #Index annotation. It will add field to datastore index. Only properties that are in the index can be searchable. Filter method is one of them.
#Id
Long id;
#Index
private HealthVault healthVault;
#Index
private String googleId;
P.S. delete your object with googleId jochen.bauer#gmail.com and write it again to database after you updated your entity. And objectify will find it.
First add #Index in your fields model. I didn't see filterVal as an email in your model. Even so, to get the entity based in your filterVal assuming that is googleId is the field of your entity.
User user = OfyService.ofy().load().type(User.class).filter("googleId", filterVal).now();
And so if your filterKey is the id of your entity.
User user = OfyService.ofy().load().key(Key.create(User.class, filterKey)).now();
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);
I'm trying to remove an entity from memory (at the moment I don't use DB) with JPA, when I use remove and then try to find the deleted entity it shows null, but when I use findAll method it retrieve all data (with removed entity)...
Profile.java
#Entity
#Table(name = "profile")
public class Profile {
#Id
#GeneratedValue
private Long id;
private String nombre;
private Boolean restrictedAccess;
private Boolean canValidate;
// private Set<AccessField> accessFields = new HashSet<AccessField>();
// private Set<AccessEntity> accessEntities = new HashSet<AccessEntity>();
#OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
private Set<AccessMenu> menuSections = new HashSet<AccessMenu>();
#OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
private Set<User> users = new HashSet<User>();
[getters and setters]
ProfileRepository
#Repository
#Transactional
public class ProfileRepository {
#PersistenceContext
private EntityManager entityManager;
public Profile save(Profile p) {
p = this.entityManager.merge(p);
this.entityManager.flush();
return p;
}
public void delete(Long id){
Profile profile = this.entityManager.find(Profile.class, id);
this.entityManager.remove(profile);
}
public List<Profile> findAll() {
CriteriaQuery cq = this.entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(Profile.class));
return (List<Profile>) this.entityManager.createQuery(cq).getResultList();
}
public Profile findById(Long id){
return this.entityManager.find(Profile.class, id);
}
}
Controller method
#RequestMapping(value="profile/delete/{idProfile}", method = RequestMethod.GET)
public String delete(#PathVariable String idProfile,RedirectAttributes ra, Model model){
profileRepo.delete(Long.valueOf(idProfile));
model.addAttribute("profiles", profileRepo.findAll());
return "profile/list";
}
if you are are trying to delete an entity by using Id in the controller, do it like profileRepo.deleteById(Long.valueOf(idProfile));
this, not like this profileRepo.delete(profileRepo.findById(Long.valueOf(idProfile)));
Also use your repository functions like these,
public void deleteArtistById(Long artistId) {
Artist artist = manager.find(Artist.class, artistId);
if (artist != null) {
manager.getTransaction().begin();
manager.remove(artist);
manager.getTransaction().commit();
}
}
public void deleteArtist(Artist artist) {
manager.getTransaction().begin();
manager.remove(artist);
manager.getTransaction().commit();
}
You can take a look at this link for more detail:
http://kodejava.org/how-do-i-delete-entity-object-in-jpa/
At last I found a solution, the problem was when I tried to remove Profile, users and menuSections have related data, so finally I put in menuSections a cascade = CascadeType.REMOVE and in users set profile property to null
I'm using Spring security for the login. I have the User.java which contains user-details.
#Entity(name = "user_table")
//#Table(name = "user_table")
public class User {
#Id
#Column(name = "id")
private String userId;
#Column(name = "email" ,unique = true)
private String userEmail;
#Column(name = "password")
private String userPassword;
//getter and setters
}
I'm getting the whole data of the current user from the table by using spring security. This is the code:
public User findUserByEmail(String email) {
List<User> users = new ArrayList<User>();
try{
users = sessionFactory.getCurrentSession().createQuery("from user_table where email= ?").setParameter(0, email).list();
System.out.println("user is " +users);
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
if (users.size() > 0) {
return users.get(0);
} else {
return null;
}
}
#Override
public User getCurrentUser() {
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
User currentUser = new User();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetails = (UserDetails) auth.getPrincipal();
System.out.println("User has authorities: "
+ userDetails.getAuthorities());
System.out.println("USERNAME:: "+userDetails.getUsername());
currentUser = findUserByEmail(userDetails
.getUsername());
System.out.println("currentUser "+currentUser);
System.out.println("currentUser "+currentUser.getUserId());
return currentUser;
}
return null;
}
What I want is to send the user id which I'm getting from currentUser.getUserId() to some other method. In that method I'm mapping to some other table like user_detail table where id is primary key. By sending id, I will get the other user_details which are not present in the user_table.
This is my UserDetail:
#Entity(name = "user_detail")
#Table(name = "user_detail")
public class UserDetail {
#Id
#GeneratedValue
#Column(name = "id")
private String userId;
//some other details like Address .
//getter and setter.
}
From controller I'm calling the above method like this:
UserService userService = new UserService();
User user=userDao.getCurrentUser();
String userId = user.getUserId();
System.out.println(userId);
UserDetail u=userDao.findUserById(userId);
and this is the method where I pass the current user id :
public UserDetail findUserById(String id) {
// TODO Auto-generated method stub
List<String> users = new ArrayList<String>();
try{
users = sessionFactory.getCurrentSession().createQuery("from user_detail where id= ?").setParameter(0, id).list();
System.out.println("user is " +users);
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
if (users.size() > 0) {
return null;
} else {
return null;
}
}
Now the result I'm getting here is null . Like user is null. What I'm doing wrong here?
There are several problems in your code. Just to point out some of them:
UserService userService = new UserService(); - you're manually creating the service object and not letting Spring-MVC injecting it into your controller, i.e. :
#Autowired
private UserService userService ;
UserDAO should be injected in your service, and not called from your controller :
class UserServiceImpl implements UserService{
#Autowired
private UserDAO userDAO;
}
All operations from your controller should call services methods and not DAO's methods. The service should use the DAO for database access. i.e.
UserDetail u=userDao.findUserById(userId);
should become
UserDetail u = userService.findUserById(userId);
and in your service :
class UserServiceImpl implements UserService{
#Autowire
private UserDAO userDAO;
#Override
public UserDetail findUserById(Long userId){
return userDAO.findUserById(userId);
}
}
if (users.size() > 0) {
return null;
} else {
return null;
}
is always returning null. Should be :
if (`users.isEmpty()){
return users.get(0);
}else { return null;}
users = sessionFactory.getCurrentSession().createQuery("from user_detail where id= ?").setParameter(0, id).list();
Your query is wrong. You should use your current bean class name and not the table name in your query, i.e. createQuery("FROM UserDetail WHERE id = ?")