Entity with Inner class for building the entity - java

I am trying out one-to-one mapping in JPA,
here i have taken relationship between Student and Contact, each student has an contact.
i have create Student entity as follows,
#Entity
#Table(name="TBL_STUDENT")
public class Student implements Serializable{
public Student(){ }
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private Integer studentId;
#OneToOne(targetEntity=StudentContact.class,fetch=FetchType.LAZY)
#JoinColumn(name="CONTACT_ID")
private StudentContact contact;
....
....
....
}
Now the StudentContact entity as follows,
#Entity
#Table(name="TBL_STD_CONTACT")
public class StudentContact extends Serializable{
public StudentContact(){ }
#Id
#Column(name="ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer contactId;
...
...
// all the properties mapped,
public static class Builder{
private Integer contactId;
private String phoneNo;
private String streetAddr;
....
// all the properties as same as StudentContact
public Builder(String val){
this.city = val;
}
public Builder setContactId(Integer contactId) {
this.contactId = contactId;
return this;
}
// rest all the setter methods are like the above, having return type Builder
public StudentContact build(){
return new StudentContact(this);
}
}
private StudentContact(Builder builder){
this.contactId = builder.contactId;
this.city = builder.city;
this.phoneNo = builder.phoneNo;
.......
...
}
}
In the above StudentContact Entity you can see i have created an inner class Builder, whose responsibility is to build StudentContact object by using its "build" method, which you can see in below mentioned StudentTest class
Now i have written a StudentTest class which has the main method as follows,
public class StudentTest {
public static void main(String [] args){
try{
StudentDAO dao = new StudentDAO();
Student student = dao.getEntity(110);
StudentContact contact = new StudentContact.Builder("Bhubaneshwar")
.setPhoneNo("9867342313")
.setPinCode("400392")
.setState("Odhisha").build();
student.setContact(contact);
dao.updateEntity(student);
}catch(Exception e){
e.printStackTrace();
}
}
When i run StudentTest from netbeans IDE, it gives as error
Exception in thread "main" java.lang.VerifyError: Constructor must call super() or this() before return in method com.entities.StudentContact.<init>()V at offset 0
I am not able to understand this error, whether this error is because for the inner class which i have created in StudentContact class,
How can i solve this,

java.lang.VerifyError means that the bytecode is not correct. Usually it can be fixed with a full clean/rebuild of the project. (I sometimes saw it after package/class renaming, or class moving from one package to another).
As mentionned in comments : extends Serializable is not correct. (maybe the cause of your bytecode issue ?)

Related

How to apply hibernate annotations to the child class of abstract class

I have an abstract class named Staff. Instructor and Lecturer are the derived classes from the Staff superclasses. I need to use hibernate annotations into the Instructor and Lecturer classes.
Staff.java
public abstract class Staff {
private int staffID;
private String firstName;
private String lastName;
private String mobile;
private String email;
private double salary;
private String city;
private String street;
//getters and setters
}
This is the subclass and I used staffID again in the subclass to apply the #Id annotation.
Lecturer.java
#Entity
#Table(name = "lecturer")
public class Lecturer extends Staff {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int staffID;
private int lectureHours;
public int getLectureHours() {
return lectureHours;
}
public void setLectureHours(int lectureHours) {
this.lectureHours = lectureHours;
}
}
I used the service classes and controllers and the JPARepositories as usually. but the database table only contain 2 values fields only (staffID and lectureHours). as follows.
LecturerRepository.java
package com.example.backend.admin.Repositories;
import com.example.backend.admin.models.Lecturer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface LecturerRepository extends JpaRepository<Lecturer, Integer> {
}
LecturerController.java
#RestController
#RequestMapping("/lecturers")
public class LecturerController {
private static Logger logger = LoggerFactory.getLogger(LecturerController.class);
#Autowired
LecturerService lecturerService;
/**
* to insert a new lecturer
* #param lecturer new lecturer
* #return insert lecturer
*/
#PostMapping("/add")
public Lecturer addLecturer(#RequestBody Lecturer lecturer) {
Lecturer lecturer1 = null;
try {
lecturer1 = lecturerService.addLecturer(lecturer);
} catch (NullPointerException e) {
logger.error("check the payload, null pointer is throwing", e);
}
return lecturer1;
}
}
LecturerService.java
#Service
public class LecturerService {
#Autowired
LecturerRepository lecturerRepository;
/**
* to invoke save method in jpa
* #param lecturer new lecturer
* #return inserted lecturer
*/
public Lecturer addLecturer(Lecturer lecturer){
return lecturerRepository.save(lecturer);
}
}
I want to add all the fields of the Lecturer class into the database. So what should I do for that?
You need to annotate the abstract class with #MappedSuperclass, in this way your #Entity class will inherit all the attributes from the extended class.

How to set and get value from the composite key

I am trying to set the value cid in student class using SubjectMark->private String cid;
How to set and get value in my controller.
Entity's and controller method below:
#Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SubjectMark id;
private String fullName;
private Integer totalMarks;
private Double percentage;
private String grade;
//Setters and getters
}
//Composit class
#Embeddable
public class SubjectMark implements Serializable {
//Composit key
private String cid;
//Setters and getters
}
In my controller I try to set value like this:
#RequestMapping(value="getstdata",method=RequestMethod.GET)
#ResponseBody
public String getstdata(#RequestParam(value="cid")String cid){
//Some code
try{
Student st=new Student();
st.getId().setCid(cid);//Set value like this but it is getting null pointer exception
//some code
//retuen some value
}
Please help me!
1st part of question:
I am trying to set the value cid in student class using SubjectMark->private String cid; How to set and get value in my controller.
#Entity
#Table
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SubjectMark subjectMarkId;
private String otherField;
// setters, getters
}
//Composite class
#Embeddable
public class SubjectMark implements Serializable {
private String cId;
// setter, getter
}
//Controller
#GetMapping(value = "getstdata")
public String getStData(#RequestParam(value="cid") String cid) {
Student student = new Student();
student.setSubjectMark(new SubjectMark());
student.getSubjectMark().setCId(cid);//cid value dynamic
// some other code
return "";
}
2nd part of question:
Now, one of the reason null exception happens when you try to call a method(either setter or getter) from a null object.
you need to write a get set method in your class I guess...
try writing something like
private String cid;
public String Cid { get => cid; set => cid = value; }

Spring boot CrudRepository saves bad data

i have problem with saving data in DB.I'm new in Spring Boot. When i run my program the result of writen data is: packagename#randomcode example:com.abc.patient.Patient#6e3e681e
This is my Entity class - Patient.java
#Entity
public class Patient {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
// getter, setter, constructor, etc
}
This is my CrudRepo PatientRepository.java
public interface PatientRepository extends CrudRepository<Patient,Integer> {
}
This is my Service class PatientService.java
#Service
public class PatientService {
#Autowired
private PatientRepository patientRepository;
public void savePatient (String name) {
Patient patient = new Patient(name);
patientRepository.save(patient);
}
public Optional<Patient> showPatient(int id) {
return patientRepository.findById(id);
}
public List<Patient> showAllPatients() {
List<Patient> patients = new ArrayList<>();
patientRepository.findAll().forEach(patients::add);
return patients;
}
}
I think that problem in in the savePatient method in this line:
Patient patients = new Patient(name);
I checked the "name" parameter and it's in 100% correct String. I'm using Derby DB.
The only problem you have is how you are printing out your Patient class. Define a proper toString() or just debug yourself to see the resulting fields. There is no problem in your JPA implementation.
See this question for the details of default toString
Try:
public void savePatient(Patient patient) {
patientRepository.save(patient);
}

how to set a generic implementation of JpaRepository interface for all entities?

Here is my project structure:
An #MappedSuperclass base class:
#MappedSuperclass
public class BaseClass {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private long id;
//getter and setter
}
An #Entity extending the base class:
#Entity
public class Person extends BaseClass {
private String regisNumber;
private String name;
private int hPerWeek;
/**
* #param regisNumber
* #param name
* #param hPerWeek
*/
public Person(String regisNumber, String name, int hPerWeek) {
super();
this.regisNumber = regisNumber;
this.name = name;
this.hPerWeek = hPerWeek;
}
//getters and setters
}
The generic DAO:
#Repository
public interface IDao<T extends BaseClass> extends JpaRepository<T, Long> {
}
In my tests, creating a Person works fine:
#Autowired
IDao<Person> dao;
#Test
public void whenPersonEntityIsCreated_thenNoExceptions() {
Person person = new Person("mkd90ii", "manu", 24);
dao.save(person);
}
Nevertheless trying getting a Person :
#Test
public void whenPersonEntityIsUpdated_thenNoExceptions() {
Person person = dao.getOne(Long.valueOf(32768));
System.out.println(person.toString());
//Updating person...
}
generates me this error:
org.springframework.dao.InvalidDataAccessApiUsageException: Unknown entity: com.bockmoi.entities.BaseClass;
nested exception is java.lang.IllegalArgumentException: Unknown entity: com.bockmoi.entities.BaseClass
I do understand that's because BaseClass is not a javax.persistence.Entity, but why the creation works and not the reading?
Can someone explain me why this happens and how to overcome this?
It's a kind of dead end for me.
Thanks

Struts2 + Json Serialization of items

I have the following classes:
public class Student {
private Long id ;
private String firstName;
private String lastName;
private Set<Enrollment> enroll = new HashSet<Enrollment>();
//Setters and getters
}
public class Enrollment {
private Student student;
private Course course;
Long enrollId;
//Setters and Getters
}
I have Struts2 controller and I would like to to return Serialized instance of Class Student only.
#ParentPackage("json-default")
public class JsonAction extends ActionSupport{
private Student student;
#Autowired
DbService dbService;
public String populate(){
return "populate";
}
#Action(value="/getJson", results = {
#Result(name="success", type="json")})
public String test(){
student = dbService.getSudent(new Long(1));
return "success";
}
#JSON(name="student")
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
It returns me the serializable student object with all sub classes, but I would like to have only student object without the hashset returned .
How can I tell Struts to serialize only the object?
I do have Lazy loading enabled and hashset is returned as proxy class.
See the answer here which shows the use of include and exclude properties. I don't think the example clearly shows excluding nested objects however I have used it for this purpose. If you still have issues I'll post a regex which will demonstrate this.
Problem with Json plugin in Struts 2
Edit:
Here is an example of using exclude properties in an annotation which blocks the serialization of a nested member:
#ParentPackage("json-default")
#Result(type = "json", params = {
"excludeProperties",
"^inventoryHistory\\[\\d+\\]\\.intrnmst, selectedTransactionNames, transactionNames"
})
public class InventoryHistoryAction extends ActionSupport {
...
inventoryHistory is of type InventoryHistory a JPA entity object, intrnmst references another table but because of lazy loading if it were serialized it would cause an Exception when the action is JSON serialized for this reason the exclude parameter has been added to prevent this.
Note that
\\
is required for each \ character, so a single \ would only be used in the xml where two are required because of escaping for the string to be parsed right.
#Controller
#Results({
#Result(name="json",type="json"
, params={"root","outDataMap","excludeNullProperties","true"
,"excludeProperties","^ret\\[\\d+\\]\\.city\\.province,^ret\\[\\d+\\]\\.enterprise\\.userinfos","enableGZIP","true"
})
})
public class UserinfoAction extends BaseAction {
#Action(value="login")
public String login(){
if(jsonQueryParam!=null && jsonQueryParam.length()>0)
{
user = JsonMapper.fromJson(jsonQueryParam, TUserinfo.class);
}
Assert.notNull(user);
//RESULT="ret" addOutJsonData: put List<TUserinfo> into outDataMap with key RESULT for struts2 JSONResult
addOutJsonData(RESULT, service.login(user));
return JSON;
}
public class TUserinfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String userid;
private String username;
private String userpwd;
private TEnterpriseinfo enterprise;
private String telphone;
private TCity city;
......
}
public class TEnterpriseinfo implements java.io.Serializable {
private String enterpriseid;
private String enterprisename;
private Set<TUserinfo> userinfos = new HashSet<TUserinfo>(0);
.......}
before set the excludeProperties property,the result is below:
{"ret":[
{
"city":{"cityename":"tianjin","cityid":"12","cityname":"天津"
,"province": {"provinceename":"tianjing","provinceid":"02","provincename":"天津"}
}
,"createddate":"2014-01-07T11:13:58"
,"enterprise":{"createddate":"2014-01-07T08:38:00","enterpriseid":"402880a5436a227501436a2277140000","enterprisename":"测试企业2","enterprisestate":0
,"userinfos":[null,{"city":{"cityename":"beijing","cityid":"11","cityname":"北京","province":{"provinceename":"beijing","provinceid":"01","provincename":"北京市"}
},"comments":"ceshi","createddate":"2004-05-07T21:23:44","enterprise":null,"lastlogindate":"2014-01-08T08:50:34","logincount":11,"telphone":"2","userid":"402880a5436a215101436a2156e10000","username":"0.5833032879881197","userpwd":"12","userstate":1,"usertype":0}]
}
,"lastlogindate":"2014-01-08T10:32:43","logincount":0,"telphone":"2","userid":"402880a5436ab13701436ab1b74a0000","username":"testUser","userpwd":"333","userstate":1,"usertype":0}]
}
after set the excludeProperties property,there are not exist province and userinfos nodes, the result is below:
{"ret":
[{
"city":{"cityename":"tianjin","cityid":"12","cityname":"天津"}
,"createddate":"2014-01-07T11:13:58"
,"enterprise":{"createddate":"2014-01-07T08:38:00","enterpriseid":"402880a5436a227501436a2277140000","enterprisename":"测试企业2","enterprisestate":0}
,"lastlogindate":"2014-01-08T11:05:32","logincount":0,"telphone":"2","userid":"402880a5436ab13701436ab1b74a0000","username":"testUser","userpwd":"333","userstate":1,"usertype":0
}]
}

Categories

Resources