Android Sqlite query two tables into an arraylist - java

I have the following situation:
Android sqlite database with two tables:
table1 ——1:N —— table2
table1
- int id (PK)
- text field2
- text field3
- text field N…
table2
int id (PK)
int t1_id (FK)
real field3
real field N…
Next I have the following Android java structures:
Class Table1 {
int id;
String field2;
String field3;
String fieldN…;
ArrayList<Table2> atable2;
}
Class Table2 {
int id;
int t1_id;
double field3;
double fieldN…;
}
public ArrayList<Table1> atable1 = new ArrayList<Table1>();
So, I need to select data from database to the atable1 arraylist based on a condition like the following:
select * from table1 where table1.field2 = ‘Italy’;
The question is that the arraylist atable2 inside arraylist atable1 must be selected based on the field t1_id from table2 (table2.t1_id = table1.id).
So anyone can help me to build an efficient form of doing a query (for Android sqlite) to get these data, including the data from table2?
Thanks in advance!
Best regards,
PS

There is no efficient form of loading 350000 records into memory on a mobile device.
But you don't need to, because you will not be able to show all of them on the screen at the same time.
Change your app to dynamically load only the data for the objects currently visible on the screen.

Related

How to update records in existing column using Spring JPA?

I am new to Java and spring. I have an existing database and table. I just wanted to update the records in the existing table. I have created a class and marked it with #entity annotation and I have spring.jpa.hibernate.auto-ddl set to update in application.properties.
But when I run my program it is creating new columns in the database. I don't want new columns to be added. Just wanted to map the table to the class and update existing records in the table.
Also, my table has 4 columns of which one has not null constraint on it. So when I run the program it's giving me an error saying "ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or a column being added is an identity, or timestamp column or alternatively if none of the previous conditions are satisfied the table must be empty to allow the addition of this column. Column brand_id cannot be added to a not empty table TableName because it does not satisfy these conditions." I could see on the console that it's executing alter table add column command.
Column names in the table are brandId, advanceDescription, and Aliases.
#Entity
Public class TableName {
#Id
private int recid;
private int brandId;
private String advanceDescription;
private String aliases;
}
And the newly added column name in the table is advance_description.
If I understand correctly, you don't want to change the schema of the table. Just add new data to it. To do so you need to disable auto-ddl and set it to none:
spring.jpa.hibernate.auto-ddl=none
Now the second problem is mismatched column names. Try changing your entity definition by setting a matching column name for each field. You can do it by using #Column(name="columnName") annotation. With the provided data it should be something like this:
#Entity
public class TableName {
#Id
private int recid;
#Column(name="brandId")
private int brandId;
#Column(name="advance_description")
private String advanceDescription;
#Column(name="Aliases")
private String aliases;
}
Please try show create table tableName command on db.
it will give you the schema of your table like
CREATE TABLE `tableName` (
`recid` int(11),
`brand_id` int(11) unsigned NOT NULL,
`advance_description` text,
`aliases` text,
PRIMARY KEY (`recid`),
)
#Entity
#Table("tableName")
public class TableName {
#Id
private int recid;
#Column(name="brand_id")
private int brandId;
#Column(name="advance_description")
private String advanceDescription;
#Column(name="aliases")
private String aliases;
}
i.e. now you can see from the db command you will able to see that your table have brand_id field so you want to map brand_id field in your TableName.class with brandId field so in that case you have to add #Column(name = "brand_id) onto your brandId field i.e. in db field is brand_id but in java I want to map brand_id field to brandId.
This applicable to all column. Check for rec_id,advance_description and aliases too.

Inserting data into table with foreign key using mybatis

I have 2 tables, Table 1 has a ID column which is auto generated. I have this Id as a foreign key with table 2, I am using mybatis to insert data into tables. I am stuck at point where I need to send the foreign key to insert command dynamically.
Table 1
CLM_ID (PK) AUTO GENERATED
CLM_VALUE NN UNIQUE
TABLE 2
CLM_ID (FK)
CML_VALUE1 (NN)
CML_VALUE2 (NN)
CML_VALUE3 (NN)
Upon request I am storing the data into table 1 where ID is generated automatically. when I am trying to store the data in table 2 how do I get the {ID}
If I know the value of the corresponding column I can get the ID associated with that column. But how do I pass the column name dynamically.
Sample Mapper example I have.
public class Address {
private Integer address_ID; //PK auto generated
private String name;
// getters and setters
}
public class Home {
private Integer addressID; //FK
private String Name;
}
public interface HomeMapper {
String INSERT_ADDRESS = "INSERT INTO HOMES(ADDRESS_ID, NAME) VALUES ( {addressID}, #{name})";
#Insert(INSERT_ADDRESS)
#SelectKey(**statement="SELECT ADDRESS_ID FROM ADDRESSES WHERE NAME='Mintu'**", keyProperty = "addressID", before=true, resultType=int.class)
public void insertRecord(Home homeName);
}
How do I send the values dynamically to statement?
Can someone help me to handle this situation? I am new to mybatis and not sure if this is the way to achieve this.

JPA NamedQuery without table in database

I have two tables in my database: packet_type and unit.
I've created something-like-entity class PacketTypeExt to fetch joined data from both tables.
I have simple namedquery:
#NamedQuery(name="PacketTypeExt.findAll", query="select p.price, p.unit_amount as unitAmount, u.title as unitTitle from packet_type p join unit u on (p.idunit = u.idunit)")
I also have such fields in this class:
private int idpackettype;
private float price;
private int unitAmount;
private String unitTitle;
I don't wanna create another table or view to store joined data, so I did not placed "Entity" annotation. After running the webpage I've got an error:
java.lang.IllegalArgumentException: Named query not found: PacketTypeExt.findAll
What's the fastest and the least complicated way to fetch such a data successfully ?

JPA Mapping Multi-Rows with ElementCollection

I'm trying to follow the JPA tutorial and using ElementCollection to record employee phone numbers:
PHONE (table)
OWNER_ID TYPE NUMBER
1 home 792-0001
1 work 494-1234
2 work 892-0005
Short version
What I need is a class like this:
#Entity
#Table(name="Phones")
public class PhoneId {
#Id
#Column(name="owner_id")
long owner_id;
#Embedded
List<Phone> phones;
}
that stores each person's phone numbers in a collection.
Long version
I follow the tutorial code:
#Entity
#Table(name="Phones")
public class PhoneId {
#Id
#Column(name="owner_id")
long owner_id;
#ElementCollection
#CollectionTable(
name="Phones",
joinColumns=#JoinColumn(name="owner_id")
)
List<Phone> phones = new ArrayList<Phone>();
}
#Embeddable
class Phone {
#Column(name="type")
String type = "";
#Column(name="number")
String number = "";
public Phone () {}
public Phone (String type, String number)
{ this.type = type; this.number = number; }
}
with a slight difference that I only keep one table. I tried to use the following code to add records to this table:
public static void main (String[] args) {
EntityManagerFactory entityFactory =
Persistence.createEntityManagerFactory("Tutorial");
EntityManager entityManager = entityFactory.createEntityManager();
// Create new entity
entityManager.getTransaction().begin();
Phone ph = new Phone("home", "001-010-0100");
PhoneId phid = new PhoneId();
phid.phones.add(ph);
entityManager.persist(phid);
entityManager.getTransaction().commit();
entityManager.close();
}
but it keeps throwing exceptions
Internal Exception: org.postgresql.util.PSQLException: ERROR: null
value in column "type" violates not-null constraint Detail: Failing
row contains (0, null, null). Error Code: 0 Call: INSERT INTO Phones
(owner_id) VALUES (?) bind => [1 parameter bound] Query:
InsertObjectQuery(tutorial.Phone1#162e295)
What did I do wrong?
Sadly, i think the slight difference that you only keep one table is the problem here.
Look at the declaration of the PhoneId class (which i would suggest is better called PhoneOwner or something like that):
#Entity
#Table(name="Phones")
public class PhoneId {
When you declare that a class is an entity mapped to a certain table, you are making a set of assertions, of which two are particularly important here. Firstly, that there is one row in the table for each instance of the entity, and vice versa. Secondly, that there is one column in the table for each scalar field of the entity, and vice versa. Both of these are at the heart of the idea of object-relational mapping.
However, in your schema, neither of these assertions hold. In the data you gave:
OWNER_ID TYPE NUMBER
1 home 792-0001
1 work 494-1234
2 work 892-0005
There are two rows corresponding to the entity with owner_id 1, violating the first assertion. There are columns TYPE and NUMBER which are not mapped to fields in the entity, violating the second assertion.
(To be clear, there is nothing wrong with your declaration of the Phone class or the phones field - just the PhoneId entity)
As a result, when your JPA provider tries to insert an instance of PhoneId into the database, it runs into trouble. Because there are no mappings for the TYPE and NUMBER columns in PhoneId, when it generates the SQL for the insert, it does not include values for them. This is why you get the error you see - the provider writes INSERT INTO Phones (owner_id) VALUES (?), which PostgreSQL treats as INSERT INTO Phones (owner_id, type, number) VALUES (?, null, null), which is rejected.
Even if you did manage to insert a row into this table, you would then run into trouble on retrieving an object from it. Say you asked for the instance of PhoneId with owner_id 1. The provider would write SQL amounting to select * from Phones where owner_id = 1, and it would expect that to find exactly one row, which it can map to an object. But it will find two rows!
The solution, i'm afraid, is to use two tables, one for PhoneId, and one for Phone. The table for PhoneId will be trivially simple, but it is necessary for the correct operation of the JPA machinery.
Assuming you rename PhoneId to PhoneOwner, the tables need to look like:
create table PhoneOwner (
owner_id integer primary key
)
create table Phone (
owner_id integer not null references PhoneOwner,
type varchar(255) not null,
number varchar(255) not null,
primary key (owner_id, number)
)
(I've made (owner_id, number) the primary key for Phone, on the assumption that one owner might have more than one number of a given type, but will never have one number recorded under two types. You might prefer (owner_id, type) if that better reflects your domain.)
The entities are then:
#Entity
#Table(name="PhoneOwner")
public class PhoneOwner {
#Id
#Column(name="owner_id")
long id;
#ElementCollection
#CollectionTable(name = "Phone", joinColumns = #JoinColumn(name = "owner_id"))
List<Phone> phones = new ArrayList<Phone>();
}
#Embeddable
class Phone {
#Column(name="type", nullable = false)
String type;
#Column(name="number", nullable = false)
String number;
}
Now, if you really don't want to introduce a table for the PhoneOwner, then you might be able to get out of it using a view. Like this:
create view PhoneOwner as select distinct owner_id from Phone;
As far as the JPA provider can tell, this is a table, and it will support the queries it needs to do to read data.
However, it won't support inserts. If you ever needed to add a phone for an owner who is not currently in the database, you would need to go round the back and insert a row directly into Phone. Not very nice.

Alternative solution for "union all" clause in Jasper Report Print for HQL (Hiberante Query Lanuage) query

I am using Hibernate and Jasper Report in my application. For displaying results in jasper report i am passing a HQL query as parameter. In query i am using "union all" clause
as below
select a.bedId as BED_ID, a.date as FROM_DATE, b.transferDate as TO_DATE, a.bedCharge as BED_CHARGE
from HmsIpdGeneral as a, HmsIpdTransferDetail as b
where a.mrNumber = b.mrNumber and a.ipdId = b.ipdId
and a.bedId = b.fromBedNo
union all
select c.bedId as BED_ID, c.date as FROM_DATE, d.dateDischarge as TO_DATE, c.bedCharge as BED_CHARGE
from HmsIpdGeneral as c, HmsDischargeDetail as d
where c.mrNumber = d.mrNumber and c.ipdId = d.patientId
and c.bedId = d.bedId
In above query i am collecting some values from 3 POJO files which are HmsIpdGeneral, HmsIpdTransferDetail, HmsDischargeDetail by creating subqueries to accomplish desired output.
this shows me result from the first part subquery only(which is written before "union all" clause).
How can i write HQL query without using "union all" clause for getting values from subqueries as mentioned above. Is there any way to replace "union all" clause in HQL query.
What i need is combining result from two subqueries without using "union all" clause because "union all" is not working for HQL query to display results in Jasper Report.
Please suggest me alternative solution for "union all" clause which can be applied to combine results from two subqueries.
===== Editing =======
Here i am trying to make clear my scenario. Below are the 3 pojo file structure which i have.
This application is for Hospital Management. i have to calculate the patient bed_charge and details for showing
which date to which date he was on which bed. If a patient gets admitted his BED_ID is enterd in HmsIpdGeneral table
and if he shifted to another bed then also values are enterd in HmsIpdGeneral table.
HmsIpdTransferDetail table keeps information about transfered patient and corresponding BED_ID.
HmsDischargeDetail table keeps information about discharged patient and corresponding vaccant BED_ID
I have to display the details of the patient that from which date to which date he was on which BED_ID and
have to show the BED_CHARGE.
Here is the POJO file structure (for convenience i have removed non-useful fields from the structure )
HmsIpdGeneral Table Structure // Keeps information of BED_ID that on which date which bed is allotted to whom
private Integer id;
private String mrNumber;
private String ipdId;
private String bedId; // for BED_ID
private double bedCharge; // for BED_CHARGE
private Date date; // for FROM_DATE
HmsIpdTransferDetail Table Structure // Keeps information of patient transfered to another BED_ID
private Integer transferId;
private String mrNumber;
private String ipdId;
private String fromWardCode;
private String toWardCode;
private String fromBedNo; // for BED_ID from where patient is transfered
private String toBedNo; // for NEW BED_ID where patient is transfered
private Date transferDate; // for TO_DATE
HmsDischargeDetail Table Structure // Keeps information of patient discharge and BED_ID status will become vaccant
private String mrNumber;
private String patientId; // ipdId will be inserted here
private String bedId; // for BED_ID where patient is last time shifted before discharge
private Date dateAdmission;
private Date dateDischarge; // for TO_DATE
Jasper Report Structure for specific MrNumber and IpdId (which is performed by using query)
BED_ID || FROM_DATE || TO_DATE || BED_CHARGE
For getting above Result i have mentioned my query. what can be the other way to get desired output.
i thanks to all valuable suggestion.

Categories