Spring H2 Database, Not Creating table in Database - spring

The following code is creating test.mv.db file. It also run properly and show that it has inserted data in the database.
Schema:
create table Customer (
id identity,
firstname varchar(20) not null,
lastname varchar(20) not null
);
Main Class:
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
CustomerRepository repo = ctx.getBean(CustomerRepository.class);
Customer c1 = new Customer("John", "Doe");
Customer c2 = new Customer("Jane", "Doe");
// insert
c1 = repo.save(c1);
c2 = repo.save(c2);
for(Customer t : repo.findAll()) {
System.out.println(t.getFirstName()+", "+t.getLastName());
}
ctx.close();
}
}
Config:
#Configuration
#ComponentScan
public class Config {
#Bean
public DataSource datasource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
Resource schema = new ClassPathResource("schema.sql");
ResourceDatabasePopulator dbp = new ResourceDatabasePopulator();
dbp.addScript(schema);
DatabasePopulatorUtils.execute(dbp, ds);
return ds;
}
#Bean
public JdbcOperations jdbcTemplate(DataSource ds) {
return new JdbcTemplate(ds);
}
}
Customer Class:
public class Customer {
private Long id;
private String firstName;
private String lastName;
public Customer() {}
public Customer(Long id, String firstName, String lastName) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public Customer(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
CustomerRepository Interface:
public interface CustomerRepository {
Customer findOne(long id);
Customer save(Customer cust);
List<Customer> findAll();
int update(Customer cust);
int delete (Customer cust);
}
CustomerRepositoryImpl:
#Repository
public class CustomerRepositoryImpl implements CustomerRepository {
#Autowired
private JdbcOperations jdbc;
private static final String SQL_INSERT = "insert into customer (firstname, lastname) values (?, ?)";
private static final String SQL_UPDATE = "update customer set firstname=?, lastname=? where id=?";
private static final String SQL_FIND_ONE = "select * from customer where id = ?";
private static final String SQL_FIND_ALL = "select * from customer order by lastname";
private static final String SQL_DELETE_ONE = "delete from customer where id = ?";
public Customer findOne(long id) {
return jdbc.queryForObject(SQL_FIND_ONE, new CustomerRowMapper(), id);
}
public Customer save(final Customer cust) {
KeyHolder holder = new GeneratedKeyHolder();
int rows = jdbc.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
PreparedStatement ps = conn.prepareStatement(SQL_INSERT, new String[]{"id"});
ps.setString(1, cust.getFirstName());
ps.setString(2, cust.getLastName());
return ps;
}
}, holder);
if(rows == 1) { // success, so apply ID to the customer object
cust.setId((Long)holder.getKey());
return cust;
}
return null;
}
public List<Customer> findAll() {
return jdbc.query(SQL_FIND_ALL, new CustomerRowMapper());
}
public int update(Customer cust) {
return jdbc.update(SQL_UPDATE, cust.getFirstName(), cust.getLastName(), cust.getId());
}
public int delete(Customer cust) {
return jdbc.update(SQL_DELETE_ONE, cust.getId());
}
private class CustomerRowMapper implements RowMapper<Customer> {
public Customer mapRow(ResultSet rs, int row) throws SQLException {
return new Customer(rs.getLong("id"), rs.getString("firstname"), rs.getString("lastname"));
}
}
}
Stacktrace:
Aug 14, 2017 9:45:42 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#b81eda8: startup date [Mon Aug 14 21:45:42 BDT 2017]; root of context hierarchy
Aug 14, 2017 9:45:43 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: org.h2.Driver
Aug 14, 2017 9:45:43 PM org.springframework.jdbc.datasource.init.ScriptUtils executeSqlScript
INFO: Executing SQL script from class path resource [schema.sql]
Aug 14, 2017 9:45:43 PM org.springframework.jdbc.datasource.init.ScriptUtils executeSqlScript
INFO: Executed SQL script from class path resource [schema.sql] in 28 ms.
Aug 14, 2017 9:45:43 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#b81eda8: startup date [Mon Aug 14 21:45:42 BDT 2017]; root of context hierarchy
John, Doe
Jane, Doe
Problem
But on second run previously saved data is no more there. First I checked with dbeaver, if there is any table within the database named Customer. I Could not find any.
Then I commented out the following lines -
c1 = repo.save(c1);
c2 = repo.save(c2);
from App.java
Becasue, if there are any data it will just read it from there with
for(Customer t : repo.findAll()) {
System.out.println(t.getFirstName()+", "+t.getLastName());
}
But no luck here as well.
What can be the problem please?
A working solution with derby is also welcome where the database is saved in the PC.

Related

Updating table is not happening through Setters in Spring JPA

I am new to Spring boot and Spring Data JPA . So here i am trying to implement a sample project where a employee has list of workers , while adding a new worker has employee details also to indicate that he works for particular employee. I am able to update the worker table and also fetch the details perfectly . Am trying to update Employee table as well so that while fetching a particular employee i want the list of workers associated with him also to be fetched . But that is not happening , i haven't used any query so far as it seems simple updation and i thought just save and setters would help to do so .
Employee.Java
#Entity
public class Employee {
#Id
private int empId;
private String empName;
private String location;
#OneToMany
private List<Worker> workers;
public Employee(){
}
public Employee(int empId, String empName, String location) {
super();
this.empId = empId;
this.empName = empName;
this.location = location;
}
public List<Worker> getWorkers() {
return workers;
}
public void setWorkers(List<Worker> workers) {
this.workers = workers;
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public void setWorkers(Worker worker) {
this.workers.add(worker);
}
#Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + ", location=" + location + ", workers=" + workers
+ "]";
}
/*#Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + ", location=" + location + "]";
}*/
Worker.Java
#Entity
public class Worker {
#Id
private int id;
private String name;
#ManyToOne
#JoinColumn(name="empId")
private Employee employee;
public Worker(int id, String name , int empId) {
super();
this.id = id;
this.name = name;
this.employee = new Employee(empId,"","");
}
public Worker() {
// TODO Auto-generated constructor stub
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
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;
}
WorkerController.Java
#RestController
public class WorkerController {
#Autowired
WorkerRepository workerService;
#Autowired
EmployeeRepository employeeService;
#GetMapping("/employees/{id}/workers")
public List<Worker> getAllWorker(#PathVariable("id") int empId){
return workerService.findByEmployeeEmpId(empId);
}
#PostMapping("/employees/{id}/workers")
public String addNewEmployee(#RequestParam("name") String name ,
#RequestParam("workerId") int id , #PathVariable("id") int empId){
Worker worker = new Worker();
List<Worker> workers = new ArrayList<Worker>();
worker.setId(id);
worker.setName(name);
worker.setEmployee(new Employee(empId,"",""));
workerService.save(worker);
workers.add(worker);
employeeService.findById(empId).get().setWorkers(workers);
Employee emp = new Employee();
emp = employeeService.findById(empId).get();
return "Successfully added";
}
}
After adding worker , i retrieve the following as output
[
{
"id": 108,
"name": "vijay",
"employee": {
"empId": 99,
"empName": "darsha",
"location": "mumbai",
"workers": []
}
},
{
"id": 110,
"name": "suraj",
"employee": {
"empId": 99,
"empName": "darsha",
"location": "mumbai",
"workers": []
}
}
]
but while retrieving i could see the employee table is not updated. can someone guide me .
{
"empId": 99,
"empName": "darsha",
"location": "mumbai",
"workers": []
}
You says:
"...while fetching a particular employee i want the list of workers
associated with him also to be fetched"
then you have to write a OneToMany Relationship on employee's side. What you do is you tries to fetch for each Worker one Employee which is of course working and is there in your JSON result.
Here is a OneToMany Example on Emplyees class side:
#OneToMany(mappedBy="employee", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private List<Worker> worker = new ArrayList<>();
Note: mappedBy have to refer to the variable Emplyee employee in your Worker Class.
Please try different fetch types also.
Why you are not getting your #OneToMany attributes is due fetch type is lazy by default for all #OneToMany associations like list, set.
To overcome this problem. Change the default lazy fetch to eager fetch.
Modify your entity mapping to this.
#OneToMany(mappedBy="employee", fetch=FetchType.EAGER, cascade=CascadeType.ALL) private List<Worker> worker = new ArrayList<>();
while fetching you may get recursive mapping. To avoid this just add #JsonIgnoreProperties to your employee field in worker class.
Example:
#JsonIgnoreProperties("employee")
#ManyToOne
#JoinColumn(name="empId")
private Employee employee;

org.springframework.beans.NotReadablePropertyException

In my web app, I want to build a registration form within which I wish to list all properties of a user's contact information that can be edited and saved. However, when I run my code, I get following error.
Any help will be greatly appreciated as I am new and learning as I go.
2019-01-03 17:09:58.705 ERROR 12223 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [An exception occurred processing JSP page /WEB-INF/views/enrollment/view.jsp at line 382
org.springframework.beans.NotReadablePropertyException: Invalid property 'contact' of bean class [com.intelo.model.Enrollment]: Bean property 'contact' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Here is my view.jsp
<form:form id="editRegistration" action="/enrollment/action" modelAttribute="enrollment" method="post" enctype="multipart/form-data">
<input type="hidden" name="enrollmentId" value="${enrollment.id}">
...
<c:forEach items="${contacts}" var="contact">
<div class="form-group col-md-6">
<label class="control-label">First Name</label>
<form:input class="form-control" path="contact.firstName" disabled="${allowedActions.edit? 'false' : 'true'}"/>
</div>
</c:forEach>
Here is my EnrollmentControleller:
#GetMapping("/enrollment/view")
public String viewEnrollment(#ModelAttribute("enrollment") Enrollment enrollment, Model model,
#ModelAttribute("user") Member user)
{
StateManager stateManager = StateManager.getStateManager(enrollment);
model.addAttribute("hasActions", stateManager.allowedActions(user).size() > 0);
model.addAttribute("allowedActions", stateManager.allowedActionMap(user));
model.addAttribute("isAdministrator", stateManager.getRoleInContext(user).hasAdministratorPrivilege());
model.addAttribute("pageTitle", "View Enrollment");
RegistrationDetails registrationDetails = enrollment.getRegistrationDetails();
model.addAttribute("studentInformation", registrationDetails.getStudentInformation());
model.addAttribute("healthInformation", registrationDetails.getHealthInformation());
model.addAttribute("emergencyContact", registrationDetails.getEmergencyContact());
model.addAttribute("familyInformation", registrationDetails.getFamilyInformation());
model.addAttribute("schoolHistory", registrationDetails.getSchoolHistory());
model.addAttribute("contacts", registrationDetails.getContacts());
model.addAttribute("siblings", registrationDetails.getSiblings());
model.addAttribute("preferredSite", registrationDetails.getPreferredSite());
return "enrollment/view";
}
Enrollment class:
#Entity
#Table(name="enrollments")
#OnDelete(action = OnDeleteAction.CASCADE)
public class Enrollment extends ModelObject {
#JsonProperty("firstName")
private String firstName = "";
#JsonProperty("middleName")
private String middleName = "";
#JsonProperty("lastName")
private String lastName = "";
#JsonProperty("birthDate")
#DateTimeFormat(pattern="MM/dd/uuuu")
private LocalDate birthDate = LocalDate.now();
#JsonProperty("studentGrade")
private String studentGrade = null;
#JsonProperty("registrationDate")
#JsonDeserialize(using = LocalDateDeserializer.class)
#JsonSerialize(using = LocalDateSerializer.class)
#DateTimeFormat(pattern="MM/dd/uuuu")
private LocalDate registrationDate = LocalDate.now();
#JsonIgnore
#OneToOne(fetch=FetchType.LAZY, mappedBy="enrollment", cascade={CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}, orphanRemoval=true)
#OnDelete(action = OnDeleteAction.CASCADE)
RegistrationDetails registrationDetails = null;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "programId")
private Program program = null;
#JsonIgnore
#OrderBy("date")
#OneToMany (mappedBy = "enrollment", cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
#OnDelete(action = OnDeleteAction.CASCADE)
private List<AttendanceRecord> attendanceRecords = new ArrayList<AttendanceRecord>();
public Enrollment() {
super();
setType(this.getClass().getCanonicalName());
setState(State.DRAFT);
setRegistrationDetails(new RegistrationDetails());
}
public String getStudentGrade() {
return studentGrade;
}
public void setStudentGrade(String studentGrade) {
this.studentGrade = studentGrade;
}
public List<AttendanceRecord> getAttendance() {
return attendanceRecords;
}
public void addAttendanceRecord(AttendanceRecord attendanceRecord) {
attendanceRecords.add(attendanceRecord);
attendanceRecord.setEnrollment(this);
}
public void removeAttendanceRecord(AttendanceRecord attendanceRecord) {
attendanceRecords.remove(attendanceRecord);
attendanceRecord.setEnrollment(null);
}
public LocalDate getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(LocalDate registrationDate) {
this.registrationDate = registrationDate;
}
public Program getProgram() {
return program;
}
public void setProgram(Program program) {
this.program = program;
setParent(program);
}
#Override
public ParentContext getParentContext() {
return program;
}
public RegistrationDetails getRegistrationDetails() {
return registrationDetails;
}
public void setRegistrationDetails(RegistrationDetails registrationDetails) {
if (this.registrationDetails != null)
registrationDetails.setEnrollment(null);
this.registrationDetails = registrationDetails;
registrationDetails.setEnrollment(this);
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
}
Here is my Contact class
#Embeddable
public class Contact {
String firstName = "";
String lastName = "";
String email = "";
String homePhone = "";
String dayPhone = "";
String cellPhone = "";
String relationship = "";
#Embedded
#AttributeOverrides({
#AttributeOverride(name="street", column=#Column(name="contact_street")),
#AttributeOverride(name="apartment", column=#Column(name="contact_apartment")),
#AttributeOverride(name="city", column=#Column(name="contact_city")),
#AttributeOverride(name="state", column=#Column(name="contact_state")),
#AttributeOverride(name="zipCode", column=#Column(name="contact_zipcode")),
#AttributeOverride(name="country", column=#Column(name="contact_country"))
})
Address address = new Address();
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
public String getDayPhone() {
return dayPhone;
}
public void setDayPhone(String dayPhone) {
this.dayPhone = dayPhone;
}
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
public String getRelationship() {
return relationship;
}
public void setRelationship(String relationship) {
this.relationship = relationship;
}
public Address getAddress() {
return address;
}
}

Count number of Item using Hibernate/JPA or JdbcTemplate

I am new to Spring/Hibernate/JPA. I have an entity class MovieEntity and MovieVersionEntity. MovieEntity has few details about the movie (like genre of movie) but MovieVersionEntity has more details about it (name, director...). So I want to count the number of movies (MovieVersionEntity) associated to the MovieEntity for the given type.
MovieEntity:
#Entity(name="MovieEntity")
#Table(name="Movie")
public class MovieEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Id")
private long id;
#Column(name="IsDeleted")
private boolean isDeleted;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate;
#OneToOne()
#JoinColumn(name="MovieTypeId")
private MovieTypeEntity movieTypeEntity;
#OneToMany(mappedBy="movieEntity",optional = false)
private List<MovieVersionEntity> movieVersionEntity;
#Transient
//#Formula("select count(*) from movie_version mv where mv.id=id")
private int childCount;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
public MovieTypeEntity getMovieTypeEntity() {
return movieTypeEntity;
}
public void setMovieTypeEntity(MovieTypeEntity movieTypeEntity) {
this.movieTypeEntity = movieTypeEntity;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public MovieVersionEntity getMovieVersionEntity() {
return movieVersionEntity;
}
public void setMovieVersionEntity(MovieVersionEntity movieVersionEntity) {
this.movieVersionEntity = movieVersionEntity;
}
public int getChildCount() {
return childCount;
}
public void setChildCount(int childCount) {
this.childCount = childCount;
}
}
MovieVersionEntity
#Entity(name = "MovieVersionEntity")
#Table(name="MovieVersion")
//#EntityListeners(AuditingEntityListener.class)
public class MovieVersionEntity {
#Id()
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="MovieId")
private long movieId;
#NotBlank
#Column(name="MovieName")
private String movieName;
#NotBlank
#Column(name="DirectorName")
private String directorName;
#NotBlank
#Column(name="Description")
private String description;
#Column(name="StopDate")
#Temporal(TemporalType.TIMESTAMP)
private Date stopDate;
#Column(name="DoneWatching")
private boolean doneWatching;
#Column(name="WatchDate")
#Temporal(TemporalType.TIMESTAMP)
//#CreatedDate
private Date watchDate;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
//#LastModifiedDate
private Date modifiedDate;
#ManyToOne(optional = false)
#JoinColumn(name="Id")
private MovieEntity movieEntity;
public String getMovieName() {
return movieName;
}
public void setMovieName(String movieName) {
this.movieName = movieName;
}
public String getDirectorName() {
return directorName;
}
public void setDirectorName(String directorName) {
this.directorName = directorName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStopDate() {
return stopDate;
}
public void setStopDate(Date stopDate) {
this.stopDate = stopDate;
}
public boolean isDoneWatching() {
return doneWatching;
}
public void setDoneWatching(boolean doneWatching) {
this.doneWatching = doneWatching;
}
public Date getWatchDate() {
return watchDate;
}
public void setWatchDate(Date watchDate) {
this.watchDate = watchDate;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public long getMovieId() {
return movieId;
}
public void setMovieId(long movieId) {
this.movieId = movieId;
}
public MovieEntity getMovieEntity() {
return movieEntity;
}
public void setMovieEntity(MovieEntity movieEntity) {
this.movieEntity = movieEntity;
}
}
I have written a query but I am getting sql error for it
#Query(value = "select m.*, ct.ChildCount" +
"from (" +
"select mv.id, count(movie_id) as ChildCount " +
"from movie_version mv " +
"group by mv.id" +
") as ct join movie m " +
"on ct.id = m.id;",nativeQuery = true)
List<MovieEntity> getMoviesWithCount();
Error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select mv.id, count(movie_id) as ChildCount from movie_version mv group by mv.id' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_60]
at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_60]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar:5.1.44]
at
Also, I am not sure if this is a right way to do it. Is there any other way I can save the count in the Transient variable. I tried using #Formuala too, but that does not give me 0 count.
Formula:
#Formula("select count(*) from movie_version mv where mv.id=id")
This is the first time I am dealing with Transient variable and I am not sure how it maps to the entity if its not persisted in the db.
However, #Formula worked for me. #Transient and #Formula cannot go together. #Formula is read only so I do not have to worry about the data being persisted.
http://outbottle.com/hibernate-populating-an-unmapped-entity-field-with-count-using-formula/

how does we enhance presistent class

AS I am new to JDO and datastore
I have set up a simple Google App Engine project based on Spring Framework to Perform Basic CRUD operation.
When I run my Application Its Show's
Persistent class "Class com.pandian.model.Customer does not seem to have been enhanced. You may want to rerun the enhancer and check for errors in the output." has no table in the database, but the operation requires it. Please check the specification of the MetaData for this class.
Customer
#PersistenceCapable
public class Customer {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
#Persistent
private String name;
#Persistent
private String email;
#Persistent
private Date date;
public Key getKey() {
return key;
}
public void setKey(Key key) {
this.key = key;
}
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 Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Customer() {
super();
}
Controller
#Controller
#RequestMapping("/customer")
public class CustomerController {
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String getAddCustomerPage(ModelMap model) {
return "add";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView add(HttpServletRequest request, ModelMap model) {
String name = request.getParameter("name");
String email = request.getParameter("email");
Customer c = new Customer();
c.setName(name);
c.setEmail(email);
c.setDate(new Date());
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(c);
} finally {
pm.close();
}
return new ModelAndView("redirect:list");
}
#RequestMapping(value = "/update/{name}", method = RequestMethod.GET)
public String getUpdateCustomerPage(#PathVariable String name,
HttpServletRequest request, ModelMap model) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Query q = pm.newQuery(Customer.class);
q.setFilter("name == nameParameter");
q.setOrdering("date desc");
q.declareParameters("String nameParameter");
try {
#SuppressWarnings("unchecked")
List<Customer> results = (List<Customer>) q.execute(name);
if (results.isEmpty()) {
model.addAttribute("customer", null);
} else {
model.addAttribute("customer", results.get(0));
}
} finally {
q.closeAll();
pm.close();
}
return "update";
}
#RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(HttpServletRequest request, ModelMap model) {
String name = request.getParameter("name");
String email = request.getParameter("email");
String key = request.getParameter("key");
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Customer c = pm.getObjectById(Customer.class, key);
c.setName(name);
c.setEmail(email);
c.setDate(new Date());
} finally {
pm.close();
}
// return to list
return new ModelAndView("redirect:list");
}
#RequestMapping(value = "/delete/{key}", method = RequestMethod.GET)
public ModelAndView delete(#PathVariable String key,
HttpServletRequest request, ModelMap model) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Customer c = pm.getObjectById(Customer.class, key);
pm.deletePersistent(c);
} finally {
pm.close();
}
PMF
public final class PMF {
private static final PersistenceManagerFactory pmfInstance = JDOHelper
.getPersistenceManagerFactory("transactions-optional");
private PMF() {
}
list//JSP
....
<%
if(request.getAttribute("customerList")!=null){
List<Customer> customers =
(List<Customer>)request.getAttribute("customerList");
if(!customers.isEmpty()){
for(Customer c : customers){
%>
<tr>
<td><%=c.getName() %></td>
<td><%=c.getEmail() %></td>
...
Any body help me out from this.....
When you looked at the AppEngine docs for using JDO, you would have come across
https://developers.google.com/eclipse/docs/appengine_orm
This tells you HOW to enhance classes for use with JDO.

Accessing Subclass properties in a JavaFX TableView ObservableArrayList

I am trying to access getter properties in a subclass with a TableView in JavaFX. I have the following class:
public class PersonType implements Serializable {
private static final long serialVersionUID = 1L;
Person person;
short count;
public PersonType() {
}
public PersonType(Person person, short count) {
super();
this.person = person;
this.count = count;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public short getCount() {
return count;
}
public void setCount(short count) {
this.count = count;
}
Person is like this:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
String firstName;
String lastName;
public Person() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Okay - lastly we have the following:
#FXML
private TableColumn tcFirstName;
#FXML
private TableColumn tcLastName;
#FXML
private TableView tblPersonTypes;
ArrayList<PersonType> pType = new ArrayList<PersonType>();
//Can assume that pType here has say 5 entries, the point of this
//is I'm trying to get to the firstName, lastName properties of the
//PersonType in the TableView below like the following:
tcFirstName.setCellValueFactory(new PropertyValueFactory<String,String>("firstName"));
tcLastName.setCellValueFactory(new PropertyValueFactory<String,String>("lastName"));
//Populate Table with Card Records
ObservableList<PersonType> data = FXCollections.observableArrayList(pType);
tblPersonTypes.setItems(data);
And I'm unsure how with a list of PersonTypes I can tell the table columns that I want the firstName and lastName properties of the Person object contained within. I know I could create a new object, and have the "count" from PersonTypes, then the other properties of "firstName", "lastName" etc without having an object property of Person. Any help would be greatly appreciated.
-- EDIT --
Another way I thought to do this was using CellFactories - where I would pass in to the CellValueFactories the Person object, then set the CellFactory to return a String value (firstName for the first name column, etc). And it would look like this:
tcFirstName.setCellValueFactory(new PropertyValueFactory<Person,String>("person"));
tcFirstName.setCellFactory(new Callback<TableColumn<Person,String>,TableCell<Person,String>>(){
#Override
public TableCell<Person,String> call(TableColumn<Person,String> param) {
TableCell<Person,String> cell = new TableCell<Person,String>(){
#Override
public void updateItem(String item, boolean empty) {
if(item!=null){
setGraphic(new Label(item.getFirstName()));
}
}
};
return cell;
}
});
Try this:
tcFirstName.setCellValueFactory(new Callback<CellDataFeatures<PersonType, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<PersonType, String> p) {
// p.getValue() returns the PersonType instance for a particular TableView row
if (p.getValue() != null && p.getValue().getPerson() != null) {
return new SimpleStringProperty(p.getValue().getPerson().getFirstName());
} else {
return new SimpleStringProperty("<No TC firstname>");
}
}
});
}

Resources