I am working with Postgres set up as an external persistent store for Ignite and want to know what ways there are to define caches for objects who’s data is spread over multiple tables.
E.G. for to work with this Person and Car class and their tables below, I have provided my own Implementation of the CacheStore. This approach seems to be very verbose however as I need to manually assign the field values myself. Are there any other methods I could be using to do this?
Person Class:
public class PersonMO{
private int id;
private String name;
private String address;
private Set<Car> cars
public PersonMO() {};
public PersonMO(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return "ID: "+id +", Name: "+name+" AD: " +address;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
public Set<Car> getCars() {
return cars;
}
}
Car Class
public class Car {
int id;
private String name;
public Car(int id, String name) {
this.id = id;
this.name = name;
}
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;
}
}
CacheStore implmentation
public class PersonMOCacheStore implements CacheStore<Integer, PersonMO>{
#SpringResource(resourceName = "pgDataSource")
private DriverManagerDataSource pgDataSource;
#LoggerResource
private IgniteLogger log;
//public void loadCache(IgniteBiInClosure<Integer, PersonMO> clo, #Nullable Object... args)
#Override
public void loadCache(IgniteBiInClosure<Integer, PersonMO> clo, Object... args)
throws CacheLoaderException {
log.info(">> Loading cache from store...");
try(Connection conn = pgDataSource.getConnection()){
try(PreparedStatement st = conn.prepareStatement("select * from PERSON")){
try(ResultSet rs = st.executeQuery()){
while(rs.next()) {
PersonMO person = new PersonMO(rs.getInt(1),rs.getString(2), rs.getString(3));
person.setCars(getCarSet(conn, person.getId() ) );
clo.apply(person.getId(), person);
}
log.info(">> Finished Loading cache from store...");
}
}
}catch(SQLException e) {
throw new CacheLoaderException("Failed to load values from cache store.",e);
}
}
//implementation for IgniteCache.get
#Override
public PersonMO load(Integer key) throws CacheLoaderException {
log.info(">> Loading person from store...");
try (Connection conn = pgDataSource.getConnection()) {
try(PreparedStatement st = conn.prepareStatement("select * from PERSON where id = ?")){
st.setString(1, key.toString());
ResultSet rs = st.executeQuery();
if(rs.next()) {
PersonMO p= new PersonMO(rs.getInt(1),rs.getString(2), rs.getString(3));
//p.setCars( getCarSet(conn, p.getId() ) );
return p;
}else {
return null;
}
}
}catch(SQLException e) {
throw new CacheLoaderException("Failed to load values from cache store.",e);
}
}
private Set<Car> getCarSet(Connection conn, int personId) throws SQLException{
Set<Car> carSet = new HashSet<Car>();
PreparedStatement st = conn.prepareStatement("select * from CAR where id = "+ personId);
ResultSet rs = st.executeQuery();
while(rs.next()) {
carSet.add(new Car(rs.getInt(1),rs.getString(2) ));
}
return carSet;
}
//other methods needed left out for sake of simplicity
}
You can use CacheJdbcPojoStore to populate caches. Then the data may be accessed via SQL or key/value APIs.
However, it's not much less verbose :)
https://www.gridgain.com/docs/latest/developers-guide/persistence/external-storage#cachejdbcpojostore
Related
Hello I'm trying to display the Student data with his corresponding subject based on the subject_id foreign key and displaying the result on GET REQUEST. I don't know how I need to rewrite the SQL command to remove the error. Here is the Error:
java.sql.SQLSyntaxErrorException: 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 'INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=3' at line 1Retrieve not successful
Here is my DB schema:
Here is my code:
public ArrayList<Object> getStudentSubject(int id) throws Exception {
Connection connection = null;
ArrayList<Student> data = new ArrayList<>();
ArrayList<Subject> data2=new ArrayList<>();
ArrayList<Object> data3 = new ArrayList<>();
try {
connection = new MysqlDbConnectionService().getConnection();
String select ="SELECT student.user_id, student.username, student.password, student.fullname,student.email, subject.id,subject.name" +
"FROM student INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=?";
PreparedStatement ps = connection.prepareStatement(select);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
Student model = new Student();
Subject model2 = new Subject();
while (rs.next()) {
model.setId(rs.getString("user_id"));
model.setUsername(rs.getString("username"));
model.setPassword(rs.getString("password"));
model.setFullName(rs.getString("fullname"));
model.setEmail(rs.getString("email"));
model2.setId(rs.getInt("id"));
model2.setName(rs.getString("username"));
data.add(model);
data2.add(model2);
data3.add(data);
data3.add(data2);
}
} catch (Exception e) {
System.out.println(e + "Retrieve not successful");
}
return data3;
}
Jersey Code:
#Path("subject/{id}")
#GET
public Response getStudentwithSubject(#PathParam("id") int id) throws Exception {
return Response.ok(new Gson().toJson(studentService.getStudentSubject(id))).build();
}
Student Model:
package com.common.db.domain;
import com.google.gson.annotations.SerializedName;
public class Student {
#SerializedName("id")
private String id;
#SerializedName("username")
private String username;
#SerializedName("password")
private String password;
#SerializedName("fullname")
private String fullName;
#SerializedName("email")
private String email;
public Student()
{
}
public Student(String id, String username, String password, String fullName, String email)
{
super();
this.id=id;
this.username = username;
this.password = password;
this.fullName = fullName;
this.email = email;
}
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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Subject Model:
package com.common.db.domain;
import com.google.gson.annotations.SerializedName;
public class Subject {
#SerializedName("id")
private int id;
#SerializedName("name")
private String name;
public Subject() {
this.id = id;
this.name=name;
}
public void setId(int id)
{
this.id=id;
}
public int getId()
{
return id;
}
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
It is a simply wrong SQL formed because of string concatenation, if you observe there is no space between subject.name and FROM student. Add space either after subject.name or before FROM like below.
String select ="SELECT student.user_id, student.username, student.password, student.fullname,student.email, subject.id,subject.name " +
" FROM student INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=?";
Let me know if this helps.
I'm trying to save a Customer record here, using preparedstatementcreator.
public Customer saveRecord(Customer customer) {
int result = 0;
try {
KeyHolder keyHolder = new GeneratedKeyHolder();
result = jdbcTemplate.update(new PreparedStatementCreator() {
#Override
public PreparedStatement createPreparedStatement(Connection connection)
throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(SQL_INSERT_CUSTOMER_MASTER_WITH_AUTO_INCREMENT, Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, customer.getFirstname());
return preparedStatement;
}
}, keyHolder);
} catch (DataAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result > 0 ? customer : null;
}
And here is my Customer object.
public class Customer implements Serializable{
private long id;
private String firstname;
private String secondname;
private int age;
private String address;
private Country country;
private String[] language;
public Customer() {
}
public Customer(String firstname, String secondname, int age, String address, Country country, String[] language) {
this.firstname = firstname;
this.secondname = secondname;
this.age = age;
this.address = address;
this.country = country;
this.language = language;
}
//getters setters
}
I understand the reason here is we cannot access customer object from inside of createPreparedStatement().
So kind of modification I can do to original Customer object class to make it visible inside of this inner class?
I have an application which accesses an oracle-db which is storing contacts in a table. create, read and update is working fine. But delete won't work only sometimes for some weird reason.
When i start my application, i load all current contacts from my db and put them in a javafx-table. i let hibernate show me all it's sql and thats all it did until here. It only did once a select. Now if i directly start to delete contacts it works fine for 3-4 contacts and then i get an error which tells me, that hibernate tried to run an update-statement where it used as id null. why is hibernate doing this?
this is total nonsense. i double and tripple checked it and there is no db-action running between the select statement and the deletes. why does hibernate do an update in the middle of nowhere without any reason when i tell it to delete?
Here you see all coude and information you can possibly need to understand my situation
public void refresh() {
List<OrganisationContact> allContacts = EntityStore.ORGA_CON_REPO
.readAllWithDetails();
contactTable.getItems().setAll(allContacts);
}
This is the method in my repository
#Override
public List<OrganisationContact> readAllWithDetails() {
try {
JPAJinqStream<Contact> stream = getStreamForTable(Contact.class);
List<OrganisationContact> organisationContactList = new ArrayList<OrganisationContact>();
try {
stream.forEach(con -> organisationContactList
.add(new OrganisationContact(con)));
} catch (javax.persistence.PersistenceException exception) {
NoReplyFromDatabaseException.showErrorDialog();
throw new NoReplyFromDatabaseException(exception);
}
stream.close();
return organisationContactList;
} catch (javax.persistence.PersistenceException exception) {
NoReplyFromDatabaseException.showErrorDialog();
throw new NoReplyFromDatabaseException(exception);
}
}
This is the method in my abstract repository my normal repository is using
protected <TableEntity>JPAJinqStream<TableEntity> getStreamForTable(final Class<TableEntity> pEntityClass) {
if (this.manager != null && this.factory != null && this.provider != null) {
if (this.manager.isOpen() && this.factory.isOpen()) {
return this.provider.streamAll(this.manager, pEntityClass);
}
}
return null;
}
manager is an instance of EntityMananger
factory is an instance of EntityManagerFactory
provider is an instance of JinqJPAStreamProvider
This is the code which is executed when you delete a contact
#FXML
public void onDelete() {
EntityStore.ORGA_CON_REPO.delete(EntityStore.CURRENT_CONTACT);
if (!UnitOfWork.closeTransaction(EntityStore.ORGA_CON_REPO, true)) {
// error occured
}
// ignore that stuff
EntityStore.CURRENT_CONTACT = null;
ModeManager.clearMode();
ModeManager.refreshTable();
}
ORGA_CON_REPO is my repository from above
UnitOfWork knows all existing repositories (in this case only 1 exists) and handles it's transactions
This is my UnitOfWork class
public final class UnitOfWork {
private static final Map<AbstractRepository<?>, EntityManager> units = new HashMap<AbstractRepository<?>, EntityManager>();
private UnitOfWork() {
}
/* PUBLIC */
/**
* Executes a commit/rollback and closes the transaction for the passed
* repository.
*
* #param pRepository
* The repository the transaction belongs to.
* #param pCommit
* If this parameter is <code>true</code>, the transaction will
* be commited before closing. If it is <code>false</code>, the
* transaction will be rolled back before closing.
* #return true if the transaction has been closed successfully, false if an error occured while closing or the manager was null
*/
public synchronized static boolean closeTransaction(
final AbstractRepository<?> pRepository, final boolean pCommit) {
EntityManager manager = units.get(pRepository);
if (manager != null) {
try {
EntityTransaction t = manager.getTransaction();
if (t.isActive()) {
if (pCommit) {
t.commit();
} else {
t.rollback();
}
}
units.remove(pRepository);
return true;
} catch (PersistenceException pException) {
pRepository.resetManager(false);
units.remove(pRepository);
// TODO: log and throw
}
}
return false;
}
/* PROTECTED */
/**
* Starts a new transaction in a new unit of work.
*
* #param pRepository
* The repository the transaction belongs to.
* #param pManager
* The EntityManager of the passed repository.
* #return <code>true</code> if the transaction has been started
* successfully, <code>false</code> if the manager is closed or one
* of the parameters is null.
*/
protected synchronized static boolean beginTransaction(
final AbstractRepository<?> pRepository,
final EntityManager pManager) {
if (pRepository != null || pManager != null) {
if (pManager.isOpen()) {
if (!units.containsKey(pRepository)) {
EntityTransaction t = pManager.getTransaction();
if (!t.isActive()) {
t.begin();
}
units.put(pRepository, pManager);
}
return true;
}
}
return false;
}
}
This is the delete method of my repository
#Override
public boolean delete(OrganisationContact pEntity) {
Contact contactEntity = pEntity.getContact();
return remove(contactEntity);
}
which is using the method of my abstract repository
protected boolean remove(final Object pEntity) {
if (this.canManagerExecute(pEntity)) {
if (this.beginTransaction()) {
this.manager.remove(pEntity);
return true;
}
}
return false;
}
private boolean canManagerExecute(final Object pEntity) {
if (this.manager != null && pEntity != null) {
return this.manager.isOpen();
}
return false;
}
which is using hibernate.
And this are my entities
#Entity
#Table(schema = "reskonverw")
public class Contact {
#Column(name = "phonenumber")
private String phoneNumber;
#Column(name = "firstname")
private String firstName;
#Column(name = "surname")
private String surname;
#Column(name = "email")
private String email;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name="id")
private int id;
#ManyToOne(cascade = CascadeType.ALL)
private Organisation organisation;
#ManyToOne(cascade = CascadeType.ALL)
private Role role;
public Contact() {
}
public Contact(String phoneNumber, String firstName, String surname,
String email, Organisation organisation, Role role) {
this.phoneNumber = phoneNumber;
this.firstName = firstName;
this.surname = surname;
this.email = email;
this.organisation = organisation;
this.role = role;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Organisation getOrganisation() {
return organisation;
}
public void setRole(final Role pRole) {
role = pRole;
}
public Role getRole() {
return role;
}
public void setOrganisation(Organisation organisation) {
this.organisation = organisation;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public String toString() {
return new StringBuilder(surname).append(", ").append(firstName)
.toString();
}
}
#Entity
#Table(schema = "reskonverw")
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
private String name;
public Country() {
}
public Country(String cName) {
this.name = cName;
}
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;
}
#Override
public String toString() {
return name;
}
}
#Entity
#Table(schema = "reskonverw")
public class Organisation {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
private String name;
private String zipcode;
private String housenumber;
private String city;
private String street;
#ManyToOne(cascade = CascadeType.ALL)
private Country country;
public Organisation() {
}
public Organisation(String name, String zipcode, String housenumber,
String city, String street, Country country) {
this.name = name;
this.zipcode = zipcode;
this.housenumber = housenumber;
this.city = city;
this.street = street;
this.country = country;
}
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 getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getHousenumber() {
return housenumber;
}
public void setHousenumber(String housenumber) {
this.housenumber = housenumber;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
#Override
public String toString() {
return name;
}
}
#Entity
#Table(schema = "reskonverw")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
private String description;
public Role() {
}
public Role(String rDescription) {
this.description = rDescription;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return description;
}
}
My session bean which is used to be displayed in the javafx table
public class OrganisationContact {
private Contact contact;
public OrganisationContact(Contact contact) {
this.contact = contact;
}
/* Entities */
public Organisation getOrganisation() {
return contact.getOrganisation();
}
public void setOrganisation(Organisation organisation) {
contact.setOrganisation(organisation);
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public Role getRole() {
return contact.getRole();
}
public void setRole(final Role pRole) {
contact.setRole(pRole);
}
public Country getCountry() {
return contact.getOrganisation().getCountry();
}
public void setCountry(final Country pCountry) {
contact.getOrganisation().setCountry(pCountry);
}
/* EntityStats */
// Organisation
public String getOrganisationName() {
return contact.getOrganisation().getName();
}
public void setOrganisationName(final String pName) {
contact.getOrganisation().setName(pName);
}
public String getOrganisationZipcode() {
return contact.getOrganisation().getZipcode();
}
public void setOrganisationZipcode(final String pZipcode) {
contact.getOrganisation().setZipcode(pZipcode);
}
public String getOrganisationHousenumber() {
return contact.getOrganisation().getHousenumber();
}
public void setOrganisationHouseNumber(final String pHouseNumber) {
contact.getOrganisation().setHousenumber(pHouseNumber);
}
public String getOrganisationCity() {
return contact.getOrganisation().getCity();
}
public void setOrganisationCity(final String pCity) {
contact.getOrganisation().setCity(pCity);
}
public String getOrganisationStreet() {
return contact.getOrganisation().getStreet();
}
public void setOrganisationStreet(final String pStreet) {
contact.getOrganisation().setStreet(pStreet);
}
// Contact
public String getFirstName() {
return contact.getFirstName();
}
public void setFirstName(final String pFirstName) {
contact.setFirstName(pFirstName);
}
public String getSurname() {
return contact.getSurname();
}
public void setSurname(final String pSurname) {
contact.setSurname(pSurname);
}
public String getEmail() {
return contact.getEmail();
}
public void setEmail(final String pEmail) {
contact.setEmail(pEmail);
}
public String getPhoneNumber() {
return contact.getPhoneNumber();
}
public void setPhoneNumber(final String pPhoneNumber) {
contact.setPhoneNumber(pPhoneNumber);
}
// Country
public String getOrganisationCountryName() {
return contact.getOrganisation().getCountry().getName();
}
// Role
public String getRoleDescription() {
return contact.getRole().getDescription();
}
public void setRoleDescription(final String pDescription) {
contact.getRole().setDescription(pDescription);
}
}
EDIT: Here the sql hibernate prints on my console first when it does the select at the programmstart:
Hibernate:
select
*
from
( select
contact0_.id as id1_0_,
contact0_.email as email2_0_,
contact0_.firstname as firstname3_0_,
contact0_.organisation_id as organisation_id6_0_,
contact0_.phonenumber as phonenumber4_0_,
contact0_.role_id as role_id7_0_,
contact0_.surname as surname5_0_
from
reskonverw.Contact contact0_ )
where
rownum <= ?
Hibernate:
select
organisati0_.id as id1_2_0_,
organisati0_.city as city2_2_0_,
organisati0_.country_id as country_id7_2_0_,
organisati0_.housenumber as housenumber3_2_0_,
organisati0_.name as name4_2_0_,
organisati0_.street as street5_2_0_,
organisati0_.zipcode as zipcode6_2_0_,
country1_.id as id1_1_1_,
country1_.name as name2_1_1_
from
reskonverw.Organisation organisati0_
left outer join
reskonverw.Country country1_
on organisati0_.country_id=country1_.id
where
organisati0_.id=?
Hibernate:
select
role0_.id as id1_3_0_,
role0_.description as description2_3_0_
from
reskonverw.Role role0_
where
role0_.id=?
Here the sql hibernate prints on my console when it does the delete at the buttonclick (select because i update all entities afterwards because there are multiple clients):
Hibernate:
delete
from
reskonverw.Contact
where
id=?
Hibernate:
select
*
from
( select
contact0_.id as id1_0_,
contact0_.email as email2_0_,
contact0_.firstname as firstname3_0_,
contact0_.organisation_id as organisation_id6_0_,
contact0_.phonenumber as phonenumber4_0_,
contact0_.role_id as role_id7_0_,
contact0_.surname as surname5_0_
from
reskonverw.Contact contact0_ )
where
rownum <= ?
Here the sql hibernate prints on my console when it does an update instead of a delete at the buttonclick (no select because it crashes before):
Hibernate:
update
reskonverw.Contact
set
email=?,
firstname=?,
organisation_id=?,
phonenumber=?,
role_id=?,
surname=?
where
id=?
Jul 08, 2015 8:05:12 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1407, SQLState: 72000
Jul 08, 2015 8:05:12 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ORA-01407: Aktualisieren von ("RESKONVERW"."CONTACT"."ORGANISATION_ID") zu NULL nicht möglich
For not german ppl, 'ERROR: ORA-01407: Aktualisieren von ("RESKONVERW"."CONTACT"."ORGANISATION_ID") zu NULL nicht möglich' means 'error - setting resconverw.contact.organisation_id to null not possible
Contact has a foreginkey to Organisation. It is linked by the id of the Organisation. When i delete the Contact, Hibernate sometimes tries to set the foreginkey to null before deleting it. Not always for some reason i couldn't figure out yet. In my db i had setup a constraint which prevent the foregin key from becomeing null. And that is why the update failed and i got an exception. I removed the constraint and since then it is working.
Thanks all for the help
Can someone help me i have those classes, and i want read out the getAllCustomer(), but i have no idea how i can implent it in my main method.
I tried already several things, but it didn't work well. Can anyone help me? :P
public static ArrayList<Customer> getAllCustomer() throws ClassNotFoundException, SQLException {
Connection conn=DBConnection.getDBConnection().getConnection();
Statement stm;
stm = conn.createStatement();
String sql = "Select * From Customer";
ResultSet rst;
rst = stm.executeQuery(sql);
ArrayList<Customer> customerList = new ArrayList<>();
while (rst.next()) {
Customer customer = new Customer(rst.getString("id"), rst.getString("name"), rst.getString("address"), rst.getDouble("salary"));
customerList.add(customer);
}
return customerList;
}
this is my model class
public class Customer {
private String id;
private String name;
private String salary;
private String address;
public Customer (String pId, String pName, String pSalary, String pAddress) {
id = pId;
name = pName;
salary = pSalary;
adress = pAddress;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Assuming that your getAllCustomer() method is in class A . then in your main method, you do as follows
public void main(String[] args){
List<Customer> customers = A.getAllCustomer();
}
Based on the nature of your question, this JDBC tutorial will help you
The data type of your Salary field is String but you are getting the value as double.
All you need to do is to change the rst.getDouble("salary") to rst.getString("salary")
To call the method:
public static void main(String[] args)
ArrayList<Customer> customers = YourDALClass.getAllCustomer();
for(Customer c : customers){
System.out.println(c.getName());
}
}
In a web-service i have the following function which retreives some infos of a doctor and his patient based on patient's phone:
public String findDoctorOfPatient(String phone) {
AnnotationConfiguration config = new AnnotationConfiguration();
config.configure("hibernate.cfg.xml");
SessionFactory factory = config.buildSessionFactory();
Session session = factory.openSession();
session.beginTransaction();
Criteria query = session.createCriteria(doctor.class);
query.createCriteria("patients", "p");
query.add(Restrictions.eq("p.phone", phone));
List<doctor> doctorList = (ArrayList<doctor>) query.list();
session.getTransaction().commit();
String answear = "";
for (doctor d : doctorList) {
answear = answear.concat("docPhone" + d.getPhone() + "docEmail"
+ d.getEmail() + "patDia"
+ d.getPatients().iterator().next().getDiastolic()
+ "patSys"
+ d.getPatients().iterator().next().getSystolic());
}
if (doctorList.isEmpty()) {
session.close();
factory.close();
return "No Doctor!";
} else {
session.close();
factory.close();
return answear;
}
}
The problem is when i have one patient is ok , but when i add second patient it gives me the details of last patient despite i have set to criteria tha firt's patient phone!
I have 2 tables:
1.doctor(id,username,password,phone,email)
2.patient(id,name,surname,phone,systolic,diastolic,doctorid(FK refers to doctor.id))
I have configured properly the hibernate.cfg.xml.
And i have set the class for doctor and patient:
#Entity
public class doctor {
#Id
private int id;
private String username;
private String password;
private String phone;
private String email;
#OneToMany(targetEntity = patient.class, cascade = CascadeType.ALL, mappedBy = "doctor")
#Cascade(value = org.hibernate.annotations.CascadeType.ALL)
private Collection<patient> patients = new ArrayList<patient>();
public Collection<patient> getPatients() {
return patients;
}
public void setPatients(Collection<patient> patients) {
this.patients = patients;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
#Entity
public class patient {
#Id
private int id;
private String name;
private String surname;
private String phone;
private int systolic;
private int diastolic;
#ManyToOne
private doctor doctor;
public doctor getDoctor() {
return doctor;
}
public void setDoctor(doctor doctor) {
this.doctor = doctor;
}
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 getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getSystolic() {
return systolic;
}
public void setSystolic(int systolic) {
this.systolic = systolic;
}
public int getDiastolic() {
return diastolic;
}
public void setDiastolic(int diastolic) {
this.diastolic = diastolic;
}
}
In this web-service the response is always the same (given the mobile number) .
It gives me always the patSys=130 and patDia=80 which are the second's patient info!.Something must be wrong in the webservice but to me all seems ok!
You need to create Criteria object on Patient and no need to obtain transaction here.
Criteria query = session.createCriteria(Patient.class)
.add(Restrictions.eq("phone", phone));
List<Patient> patList = (ArrayList<Patient>) query.list();
String result="";
if(!patList.isEmpty()) {
Patient patient=patList.get(0);
result="Doc Phone : " + patient.getDoctor().getPhone();
}
return result;