Getting null values with data in list of collection of object - spring

I am trying to add few employee objects inside the list named collectionofEmployees here.I am able to add the data but i am getting first record for custom object attributes as nulls.The data is getting inserted after that properly.
Here is my controller.
#RestController
public class CustomController {
#Autowired
Employees collectionofEmployees;
#RequestMapping("/add")
public Employees add() {
collectionofEmployees.add(new Employee(1,"XYZ"));
collectionofEmployees.add(new Employee(3, "VTY"));
return collectionofEmployees;
}
Here is my Employees Model class which contains list of employee
#Component
public class Employees {
#Autowired
private List<Employee>employees;
public List<Employee> getEmployees() {
return employees;
}
public Employees(List<Employee> employees) {
super();
this.employees = employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public void add(Employee employee)
{
this.employees.add(employee);
}
Here is my employee class
#Component
public class Employee {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public Employee() {
super();
}
public Employee(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
The output i am getting is as {"employees":[{"id":null,"name":null},{"id":1,"name":"XYZ"},{"id":3,"name":"VTY"}]}
Help would be appreciated alot:)I want to avoid nulls

Try to remove #Component from Employee class. It is initialized by Spring and injected to your
#Autowired
private List<Employee>employees

As i still dont know how to avoid nulls at time of intialisation done by spring,for temporary purpose i have added collectionofEmployees.getEmployees().remove(0) under add method which removes the nulls from the input.

Related

Why the class attributes in the quarku panache example are PUBLIC instead of PRIVATE

Referring to the getting started link below
https://quarkus.io/guides/hibernate-orm-panache
The example uses a Entity class with public attributes.
class Person{
public String name;
}
and used as
person.name = "Synd";
so is it simply a lazy example (!! in official doc ? ) or it means something else.
According to the documentation, it might be related to a single difference (extending PanacheEntityBase)
If you don’t want to bother defining getters/setters for your entities, you can make them extend PanacheEntityBase and Quarkus will generate them for you. You can even extend PanacheEntity and take advantage of the default ID it provides.
Therefore they are making them Public for Quarkus to generate getters/setters for you automatically.
#Entity
public class Person extends PanacheEntity {
public String name;
public LocalDate birth;
public Status status;
public static Person findByName(String name){
return find("name", name).firstResult();
}
public static List<Person> findAlive(){
return list("status", Status.Alive);
}
public static void deleteStefs(){
delete("name", "Stef");
}
}
vs
#Entity
public class Person {
#Id #GeneratedValue private Long id;
private String name;
private LocalDate birth;
private Status status;
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 LocalDate getBirth() {
return birth;
}
public void setBirth(LocalDate birth) {
this.birth = birth;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}

Spring boot does not editing record in to mysql

when i updating the records via postman record not updating it will create a new record i don't know why.i attached screenshot below along with code what i tried so far.i have attched the controller,service,
entity,repository.
i am tring this since yesterday problem not solved please some one will help me to solve
enter image description here
EmployeeController
#PutMapping("/edit/{id}")
private Employee update(#RequestBody Employee employees,#PathVariable(name = "id") long id)
{
Employee emp = services.get(id);
services.saveOrUpdate(emp);
return employees;
}
Services
//updating a record
//updating a record
public void update(Employee employees, int id)
{
repo.save(employees);
}
Repository
#Repository
public interface EmployeeRepository extends CrudRepository<Employee,Long> {
}
Entity
#Entity
#Table(name="Records")
public class Employee {
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name="fname")
private String fname;
#Column(name="lname")
private String lname;
#Column(name="city")
private String city;
#Column(name="phone")
private String phone;
#Column(name="salary")
private String salary;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
}
This an example of UPDATE and it worked for me.
//HTTP PUT
#PutMapping("/owners/{id}")
public void updateOwner(#RequestBody Owner owner, #PathVariable int id) {
owner.setId(id);
ownerRepos.save(owner);
}
I used the CrudRepository too.
Also I notice that you call services.saveOrUpdate(emp) but at the same time you showed us "public void update(Employee employees, int id)" below. If'd better if you could show the definition of the method saveOrUpdate()
SaveOrUpdate uses the ID of the object to determine if the object is the same or new. When updating, you're not considering the ID of the employee. You should first fetch the Object from DB and update the same object. The updates should take place on a persistent object

null values inserted while auditing

My AuditListener
public class EmployeeAuditListeners {
#PrePersist
public void prePersist(Employee employee){
perform(employee,Action.INSERTED);
}
#PreUpdate
public void preUpdate(Employee employee){
perform(employee,Action.UPDATED);
}
#PreRemove
public void preRemove(Employee employee){
perform(employee,Action.DELETED);
}
#Transactional
public void perform(Employee emp, Action action){
EntityManager em = BeanUtil.getBean(EntityManager.class);
CommonLogs commonLogs = new CommonLogs();
commonLogs.setQuery("new query");
em.persist(commonLogs);
}
}
and My Auditable.class
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<U> {
#CreatedBy
protected U createdBy;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date createdDate;
#LastModifiedBy
protected U lastModifiedBy;
#LastModifiedDate
#Temporal(TemporalType.TIMESTAMP)
protected Date lastModifiedDate;
}
My CommonLogs.class
#Entity
#EntityListeners(AuditingEntityListener.class)
public class CommonLogs extends Auditable<String> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String query;
public CommonLogs() {
}
public CommonLogs(String query) {
this.query = query;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}
My Employee.java class
#Entity
#EntityListeners(EmployeeAuditListeners.class)
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String address;
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 getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
and I have a simple Rest Controller
#RestController
#RequestMapping("/api")
public class EmployeeController {
#Autowired
private EmployeeRepository employeeRepository;
#PostMapping("/employees")
public Employee createEmployee(#RequestBody Employee employee){
return employeeRepository.save(employee);
}
}
I want to log it on my table (common_logs) every time i perform some crud operations on my Employee Entity.
the above given example is working to some extent as it successfully stores employee and invokes EmployeeAuditListeners.
but now while saving CommongLog entity i expect it's parent class Auditable to automatically insert createdBy, createdDate etc. for now only query and id is inserted on common_logs table and remaining columns are null.
You can review the documentation for Auditing in here.
To enable the automatic Auditing, you must add the annotation #EnableJpaAuditing in your Application class:
#SpringBootApplication
#EnableJpaAuditing
class Application {
static void main(String[] args) {
SpringApplication.run(Application.class, args)
}
}
If you want the fields #CreatedBy and #LastModifiedBy too, you will also need to implement the AuditorAware<T> interface. For example:
class SpringSecurityAuditorAware implements AuditorAware<User> {
public User getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
return ((MyUserDetails) authentication.getPrincipal()).getUser();
}
}

Spring JPARepository Update a field

I have a simple Model in Java called Member with fields - ID (Primary Key), Name (String), Position (String)
I want to expose an POST endpoint to update fields of a member. This method can accept payload like this
{ "id":1,"name":"Prateek"}
or
{ "id":1,"position":"Head of HR"}
and based on the payload received, I update only that particular field. How can I achieve that with JPARepository?
My repository interface is basic -
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository("memberRepository")
public interface MemberRepository extends JpaRepository<Member, Integer>{
}
My Member model -
#Entity
#Table(name="members")
public class Member {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="member_id")
private Integer id;
#Column(name="member_name")
#NotNull
private String name;
#Column(name="member_joining_date")
#NotNull
private Date joiningDate = new Date();
#Enumerated(EnumType.STRING)
#Column(name="member_type",columnDefinition="varchar(255) default 'ORDINARY_MEMBER'")
private MemberType memberType = MemberType.ORDINARY_MEMBER;
public Member(Integer id, String name, Date joiningDate) {
super();
this.id = id;
this.name = name;
this.joiningDate = joiningDate;
this.memberType = MemberType.ORDINARY_MEMBER;
}
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 Date getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
public MemberType getMemberType() {
return memberType;
}
public void setMemberType(MemberType memberType) {
this.memberType = memberType;
}
public Member(String name) {
this.memberType = MemberType.ORDINARY_MEMBER;
this.joiningDate = new Date();
this.name = name;
}
public Member() {
}
}
Something like this should do the trick
public class MemberService {
#Autowired
MemberRepository memberRepository;
public Member updateMember(Member memberFromRest) {
Member memberFromDb = memberRepository.findById(memberFromRest.getid());
//check if memberFromRest has name or position and update that to memberFromDb
memberRepository.save(memberFromDb);
}
}

How to update entity using spring-data neo4j

My problem is when I'm trying to update entity using GraphRepository 'save' method, all my fields, that was not changed, are being rewritten with null values.
I make PUT request with only id and name, because I want change User's name, but save method automatically changes password field to null value. I wanna update only dirty values. How can I achieve this? Maybe there is some kind of merge or update methods?
My entity class looks like this:
#NodeEntity
public class User {
#GraphId Long id;
String name;
String password;
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;
}
#JsonIgnore
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My repository class looks like this:
public interface UserRepository extends GraphRepository<User> {
public User findById(Long id);
}
#Transactional
public void update(Long id, String name) {
User user = repository.findById(id);
if (user != null) {
user.setName(name);
}
}

Resources