I don't understand what kind of mysticism. This method located in class UserService:
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = repository.getByEmail(email.toLowerCase());
if (user == null) {
throw new UsernameNotFoundException("User " + email + " isn't found");
}
AuthorizedUser authorizedUser = new AuthorizedUser(user); // 1
Objects.requireNonNull(authorizedUser); // 2
System.out.println(new AuthorizedUser(user) + " 1"); // 3
int userId = authorizedUser.getId(); // 4
return authorizedUser; // 5
}
In the lines which are numbered in comments,
why does everything go smoothly in line 1-3, line 3 goes to the console:
UserTo{id=100000, name='VadimUserAdmin', email='vadim#gmail.com'} 1
And in line 4, an exception is thrown:
Caused by: java.lang.IllegalArgumentException: Entity must has id
at org.springframework.util.Assert.notNull(Assert.java:201)
at topjava.quest.HasId.id(HasId.java:14)
at topjava.quest.AuthorizedUser.getId(AuthorizedUser.java:22)
at topjava.quest.service.UserService.loadUserByUsername(UserService.java:64)
What should I do with this?
spring.security.version - 5.6.2
hibernate.version - 5.6.5.Final
class AuthorizedUser:
public class AuthorizedUser extends org.springframework.security.core.userdetails.User {
#Serial
private static final long serialVersionUID = 1L;
private UserTo userTo;
public AuthorizedUser(User user) {
super(user.getEmail(), user.getPassword(), true, true, true, true, user.getRoleSet());
setUserTo(Util.userAsTo(user));
}
public int getId() {
return userTo.id();
}
public void setUserTo(UserTo userTo) {
userTo.setPassword(null);
this.userTo = userTo;
}
#Override
public String toString() {
return userTo.toString();
}
}
class UserTo:
public class UserTo extends BaseTo implements Serializable {
#Serial
private static final long serialVersionUID = 1L;
#NotBlank
#Size(min = 2, max = 100)
#ApiModelProperty(example = "New name")
private final String name;
#Email
#NotBlank
#Size(max = 100)
#ApiModelProperty(example = "newmame#gmail.com")
private final String email;
#NotBlank
#Size(min = 6, max = 32)
#ApiModelProperty(example = "newmame123")
private String password;
#ConstructorProperties({"id", "name", "email", "password"})
public UserTo(Integer id, String name, String email, String password) {
super(id);
this.name = name;
this.email = email;
this.password = password;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public String toString() {
return "UserTo{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
class BaseTo:
public class BaseTo implements HasId {
#ApiModelProperty(hidden = true)
protected Integer id;
public BaseTo() {
}
public BaseTo(Integer id) {
this.id = id;
}
#Override
public Integer getId() {
return null;
}
#Override
public void setId(Integer id) {
this.id = id;
}
}
class HasId:
public interface HasId {
Integer getId();
void setId(Integer id);
default boolean isNew() {
return getId() == null;
}
default int id() {
Assert.notNull(getId(), "Entity must has id");
return getId();
}
}
What I do wrong?
When you call HasId.id, you call method getId() from BaseTo.class, which returns null. Change the method to
getId(){
return this.id;
}
Related
I have two entity (Instructor, InstructorDetail) which have one to one relation.
instructor_detail_id of Instructor entity has a foreign key to the id column of InstructorDetail. So, according to my requirement, when an Instructor is deleted, corresponding instructorDetail also needs to be deleted, but not the vice versa. Now, when I am trying to delete an instructorDetail, it is throwing the referencial integrity constraint error.
Note: I am using H2 db.
Following are the code snippets.
Instructor -
import javax.persistence.*;
#Table(name="instructor")
#Entity
public class Instructor implements IdentityMarker<Integer>{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="instructor_id")
private int id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "instructor_detail_id")//, referencedColumnName = "id")
private InstructorDetail instructorDetail;
public Instructor(){
}
public Instructor(String name, String email) {
this.name = name;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int 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;
}
public InstructorDetail getInstructorDetail() {
return instructorDetail;
}
public void setInstructorDetail(InstructorDetail instructorDetail) {
this.instructorDetail = instructorDetail;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
#Override
public String toString() {
return "Instructor{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", instructorDetail=" + instructorDetail +
'}';
}
}
InstructorDetail -
import javax.persistence.*;
#Table(name="instructor_detail")
#Entity
public class InstructorDetail implements IdentityMarker<Integer>{
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name="youtube_link")
private String youtubeLink;
#Column(name="hobby")
private String hobby;
#OneToOne(cascade = {
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.REFRESH
},
mappedBy = "instructorDetail")
// this bi-directional relationship enables us to get the instructor when an instructionDetail is loaded.
private Instructor instructor;
public InstructorDetail(){
}
public InstructorDetail(String youtubeLink, String hobby){
this.youtubeLink = youtubeLink;
this.hobby = hobby;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYoutubeLink() {
return youtubeLink;
}
public void setYoutubeLink(String youtubeLink) {
this.youtubeLink = youtubeLink;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
#Override
public String toString() {
return "InstructorDetail{" +
"id=" + id +
", youtubeLink='" + youtubeLink + '\'' +
", hobby='" + hobby + '\''+
'}';
}
#PreRemove
private void preRemove() {
System.out.println("pre remove call");
instructor.setInstructorDetail(null);
}
}
Following is the client code
private static void deleteInstructorDetail(){
InstructorDetailDao instructorDetailDao = new InstructorDetailDaoImpl();
InstructorDetail instructorDetail = instructorDetailDao.getInstructorDetail(2);
Instructor instructor = instructorDetail.getInstructor();
System.out.println("Instructor: " + instructor);
boolean b = instructorDetailDao.deleteInstructorDetail(instructorDetail);
assert b == true: "InstructorDetail is not deleted!";
System.out.println("Trying to load Instructor.. It should be deleted!");
InstructorDao instructorDao = new InstructorDaoImpl();
instructor = instructorDao.getInstructor(instructor.getId());
assert instructor != null: "Instructor also got deleted!";
}
Any help would be appreciated! Thanks in advance.
When I post the data that time getting this error
Cannot invoke "com.helpmydesk.Repo.UserRepo.save(Object)" because "this.userRepo" is null
at com.helpmydesk.InterFaceAndService.ServiceClass.execute(ServiceClass.java:17) ~[classes/:na]
at com.helpmydesk.ControllerClass.execute(ControllerClass.java:27) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
Main Class
#EnableJpaRepositories("package com.helpmydesk.Repo.UserRepo")
#SpringBootApplication
public class HelpmydeskApplication {
public static void main(String[] args) {
SpringApplication.run(HelpmydeskApplication.class, args);
}
}
Controller Class
#Controller
public class ControllerClass {
#Autowired
private InterfaceClass interfaceClass;
public ControllerClass(InterfaceClass interfaceClass) {
this.interfaceClass = interfaceClass;
}
#PostMapping("/doregister")
public User execute(#RequestBody User user) {
return this.interfaceClass.execute(user);
}
#RequestMapping("/")
public String home() {
return "home";
}
#RequestMapping("/singup")
public String singup() {
return "singup";
}
}
Repository Class
#Repository
public interface UserRepo extends CrudRepository<User, Integer> {
}
interface Class
public interface InterfaceClass {
public User execute(User user);
}
Service Class
#Service
public class ServiceClass implements InterfaceClass {
private UserRepo userRepo;
public User execute(User user) {
this.userRepo.save(user);
return user;
}
}
User Class
#org.hibernate.annotations.Entity
#Table(name = "USER")
public class User {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private int id;
private String name;
#Column(unique = true)
private String email;
private String password;
private String role;
private boolean enabled;
private String imageUrl;
#Column(length = 500)
private String about;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private java.util.List<Blog> blogs = new ArrayList<>();
public User() {
super();
// TODO Auto-generated constructor stub
}
public int getId() {
return id;
}
public void setId(int 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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
#Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", role=" + role
+ ", enabled=" + enabled + ", imageUrl=" + imageUrl + ", about=" + about + "]";
}
}
enter image description here
You don't have #Autowired on your UserRepo variable. You can add it; the better fix is to eliminate field injection and use an ordinary constructor. Spring will provide all of the necessary dependencies when it calls the constructor, it makes testing much easier, and it prevents problems of this sort.
you should add #Autowired in your service class before ligne UserRepo userRepo
because userRepo must be injected before using it
I work on a Java Spring boot app where I get the error of Hot-swap failed and schema change is not implemented and the operation is not supported by the VM. Afterward, the table is truncated and have no data at all.
I have 2 models provided below,
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
#NotNull
#NotEmpty
private String name;
#Column(name = "countryName")
#NotNull
#NotEmpty
private String countryName;
#Column(name = "currencyName")
#NotNull
#NotEmpty
private String currencyName;
/*
* total steps is for the keepign the history of the user movement
* */
#Column(name = "totalSteps")
#Min(value = 0L, message = "The value must be positive")
private int totalSteps;
/*
* current steps is for providing the user reward. We will need to set
* it to zero after processing the user payment
* */
#Column(name = "currentSteps")
#Min(value = 0L, message = "The value must be positive")
private int currentSteps;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RewardList> rewardLists = new ArrayList<>();
public User() {
}
public User(#NotNull #NotEmpty String name, #NotNull #NotEmpty String countryName) {
this.name = name;
this.countryName = countryName;
}
public User(#NotNull #NotEmpty String name, #NotNull #NotEmpty String countryName, #Min(value = 0L, message = "The value must be positive") int totalSteps) {
this.name = name;
this.countryName = countryName;
this.totalSteps = totalSteps;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountryName() {
return countryName;
}
public String getCurrencyName() {
return currencyName;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public int getTotalSteps() {
return totalSteps;
}
public void setTotalSteps(int totalSteps) {
this.totalSteps = totalSteps;
}
public int getCurrentSteps() {
return currentSteps;
}
public void setCurrentSteps(int currentSteps) {
this.currentSteps = currentSteps;
}
public List<RewardList> getRewardLists() {
return rewardLists;
}
public void setRewardLists(RewardList rl) {
this.rewardLists.add(rl);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getTotalSteps() == user.getTotalSteps() &&
getCurrentSteps() == user.getCurrentSteps() &&
getId().equals(user.getId()) &&
getName().equals(user.getName()) &&
getCountryName().equals(user.getCountryName()) &&
getRewardLists().equals(user.getRewardLists());
}
#Override
public int hashCode() {
return Objects.hash(getId(), getName(), getCountryName(), getTotalSteps(), getCurrentSteps(), getRewardLists());
}
#Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", countryName='" + countryName + '\'' +
", totalSteps=" + totalSteps +
", currentSteps=" + currentSteps +
'}';
}
}
#Entity
public class RewardList {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "reward")
#Min(value = 0L, message = "The value must be positive")
private double reward;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id", nullable = false)
private User user;
public RewardList() {
}
public RewardList(User user) {
this.user = user;
}
public RewardList(#Min(value = 0L, message = "The value must be positive") double reward) {
this.reward = reward;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public double getReward() {
return reward;
}
public void setReward(double reward) {
this.reward = reward;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RewardList)) return false;
RewardList list = (RewardList) o;
return Double.compare(list.getReward(), getReward()) == 0 &&
getId().equals(list.getId()) &&
getUser().equals(list.getUser());
}
#Override
public int hashCode() {
return Objects.hash(getId(), getReward(), getUser());
}
#Override
public String toString() {
return "RewardList{" +
"id=" + id +
", reward=" + reward +
", user=" + user +
'}';
}
}
The end-point where I have this issue provided below,
// $ curl -X PUT http://localhost:8080/api/v1/users/calculateReward?userId=1 | jq
#PutMapping("/calculateReward")
public ResponseEntity<Object> calculateReward(#RequestParam("userId") Long userId) {
Optional<User> optional = userService.findById(userId);
if (!optional.isPresent()) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
User user = optional.get();
double reward = user.getCurrentSteps() * Parameters.REWARD_PER_STEPS_EUR;
RewardList list = new RewardList();
list.setUser(user);
list.setReward(reward);
rewardListService.save(list);
user.setCurrentSteps(0);
user.setRewardLists(list);
userService.save(user);
JSONObject json = new JSONObject();
double convertionRateToEuro = currencyMap.get(user.getCurrencyName());
double rewardConverted = reward * convertionRateToEuro;
json.put("name", user.getName());
json.put("currency", user.getCurrencyName());
json.put("reward", rewardConverted);
return ResponseEntity.status(HttpStatus.CREATED).body(json);
}
Does anyone know what is going on and can provide a solution?
Thank you.
I find the reason and below I provide a solution. We will need to save the models based on the hierarchy. HotSwap doesn't support adding methods or hierarchy changes as indicated by the error messages. It's the limitation of Java HotSwap, not IntelliJ IDEA. The proper way of code sequence will be,
User user = optional.get();
RewardList list = new RewardList();
list.setUser(user);
list.setReward(reward);
user.setCurrentSteps(0);
user.setRewardLists(list);
// first save the User
userService.save(user);
// Then, save the RewardList as it has one to many relations
rewardListService.save(list);
I have one REST Call as
List<User> userList = (List<User>) iplUtil.getResult(user, mongoGetURL);
System.out.println("userList === "+userList);
output as
userList = [{_id={$oid=571903dae4b085317593a0d3}, nickName=aa, email=aa, password=aa, userId=1}]
No complile time error..
but this line failing in runtime
User u =userList.get(0);
getting exception at this line as
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.ipl.model.User
and model as
package com.ipl.model;
import java.io.Serializable;
import java.util.Map;
#SuppressWarnings("serial")
public class User implements Serializable {
private Map<String, String> _id;
private String nickName;
private String email;
private String password;
private int userId;
public User(String nickName,String password) {
this.nickName=nickName;
this.password=password;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User() {
// TODO Auto-generated constructor stub
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Map<String, String> get_id() {
return _id;
}
public void set_id(Map<String, String> _id) {
this._id = _id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public String toString() {
return "User [_id=" + _id + ", nickName=" + nickName + ", email=" + email + ", password=" + password
+ ", userId=" + userId + "]";
}
}
Im not getting any complie time error..why its failing in runtime
Having this class
#Entity
public class PriorityAreaKeyword {
public enum PriorityAreaKey {
ALL ("ALL", "ALL DEVICES"),
IOS ("IOS", "IOS"),
ANDROID ("ANDROID","ANDROID");
private final String name;
private final String id;
private PriorityAreaKey(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
}
#Id
private Long id;
#Column(name = "key")
#Enumerated(EnumType.STRING)
private PriorityAreaKey key;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public PriorityAreaKey getKey() {
return key;
}
public void setKey(PriorityAreaKey key) {
this.key = key;
}
public List<PriorityArea> getPriorityAreas() {
return priorityAreas;
}
public void setPriorityAreas(List<PriorityArea> priorityAreas) {
this.priorityAreas = priorityAreas;
}
}
I have in the DAO this method that is working fine:
#Override
#SuppressWarnings("unchecked")
public Set<PriorityArea> findPriorityAreas(PriorityAreaKey key) {
String jpql = "from PriorityAreaKeyword as pak where pak.key = :key";
Query query = entityManager.createQuery(jpql);
query.setParameter("key", key);
List<PriorityArea> priorityAreas = query.getResultList();
return new HashSet<PriorityArea>(priorityAreas);
}
I created a view like this v_report_beneficiary_list (id, email, priority_area_key)
/**
*
*/
#Entity
#Table(name = "v_report_beneficiary_list")
public class ReportBeneficiaryItem {
private Long id;
private String email;
private PriorityAreaKey priorityAreaKey;
/**
* #return the id
*/
#Id
public Long getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
#Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "priority_area_key")
public PriorityAreaKey getPriorityAreaKey() {
return priorityAreaKey;
}
public void setPriorityAreaKey(PriorityAreaKey priorityAreaKey) {
this.priorityAreaKey = priorityAreaKey;
}
In the DAO I've created another method like this:
#Su
ppressWarnings("unchecked")
#Override
public List<ReportBeneficiaryItem> findReportProposalXBeneficiary(ProposalExportFilter filter) {
// Create basic query
String jpql = "from " + ReportBeneficiaryItem.class.getName() + " b where b.priorityAreaKey = :key ";
// Create and execute jpa query
Query query = createQuery(jpql);
query.setParameter("key", filter.getPriorityAreaKey());
return query.getResultList();
}
That throws me a throws me an Exception Caused By: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
You are missing #Enumerated(EnumType.STRING) on ReportBeneficiaryItem#getPriorityAreaKey() as you have on PriorityAreaKeyword#key, so it's expecting numbers (enum index) in the database for that field, but finds strings
#Column(name = "priority_area_key")
#Enumerated(EnumType.STRING)
public PriorityAreaKey getPriorityAreaKey() {
return priorityAreaKey;
}