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 ?
Related
I'm trying to find the best way to map my data on ORM. I have a query which gets me data from MySQL database which look like
SELECT d.ID AS Id,
equipment.EQUIP_ID,
equipment.EQUIP_REFERENCE
FROM
tbl_devices d
INNER JOIN
tbl_equipment equipment ON equipment.EQUIP_ID = d.DEV_ID
What would be the most optimal way to get these data with Spring boot and Spring data??
Should I use #Query annotation and execute this or somehow create entities for Equipment and Devices tables and then use JPQL/HQL to join tables in a query, but then how should I map the result??
Thanks in advance.
You can use JdbcTemplate (import from org.springframework.jdbc.core.JdbcTemplate) to run the SQL statement above you wrote. After you can create a pojo to map result into it via BeanPropertyRowMapper. For example:
final String sql = "SELECT d.ID AS Id, equipment.EQUIP_ID, equipment.EQUIP_REFERENCE FROM tbl_devices d INNER JOIN tbl_equipment equipment ON equipment.EQUIP_ID = d.DEV_ID";
YourPojo result = jdbcTemplate.query(
sql,
new BeanPropertyRowMapper<>(YourPojo.class)
);
Pojo class maybe like following:
#Data
public class YourPojo {
private Long id;
private Long equipId;
private Your_type equip_reference_name;
}
A quick and dirty solution would be to use projections.
First, you create a projection interface:
public interface DeviceDetails {
Long getId();
Long getEquipId();
String getEquipReference();
}
You then modify the query to match column aliases with the projection properties:
SELECT d.ID AS id,
equipment.EQUIP_ID as equipId
equipment.EQUIP_REFERENCE As equipReference
...
Finally, you put the query method in a repository of your choice:
#Query(value =..., nativeQuery = true)
List<DeviceDetails> findDeviceDetails();
I have two tables in my database:
1. Warehouse
2. WarehouseItem
Relation between them are like listed below:
#Entity
#Table(name = "warehouse")
public class WarehouseModel {
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="warehouse")
private List<WarehouseItemModel> _items;
and
#Entity
#Table(name = "warehouseItem")
public class WarehouseItemModel {
#ManyToOne
public WarehouseModel warehouse;
and now I want to SELECT all the objects of the entity WarehouseModel:
public List getObjects(Class pClass)
{
startTime();
connect();
Session session = getSession();
Transaction lTransaction = session.beginTransaction();
List lRet = session.createCriteria(pClass).list();
lTransaction.commit();
endTime("getObjects: " + lRet.size() + " objects");
Collections.reverse(lRet);
return lRet;
}
In my database I have:
1x object in the table: Warehouse (WarehouseModel.java)
5x objects in the table: WarehouseItem (WarehouseItemModel.java)
When I want to retrive all the Warehouses including related WarehouseItems:
databaseConnector.eDocumentConnector.getObjects(WarehouseModel.class)
the result is:
- 5x the same object of WarehouseModel
It seems that there is dependancy that I always get as much entities of the same WarehouseModel as there is WarehouseItemModels inside field WarehouseModel._items
How to fix it and why it happens? (I have more relations like this one in my project and if it happends here, maybe it happends also in the other places)
Project details:
- Java 1.8
- Hibernate 5.0.7
- database: PostgreSQL 9.5.2
It is solved by using DISTINCT in hibernate query:
session.createCriteria(pClass).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
More importantly, you should understand how a 1-to-many relationship works in SQL.
The raw select statement is going to be something like
SELECT
.
.
<what columns you want>
.
FROM
warehouse w
JOIN warehouseItem wi ON (w.id = wi.warehouse_id)
WHERE
<whatever you need to filter on>
When you join, you're always going to get the number of rows that are related to the primary table's ID. Since there are 5 rows in the child table, 5 rows are returned, where the warehouse columns are duplicated each time but the warehouseItem columns are unique to each row.
I'm quite the rookie with JPA/JPQL, so please excuse me if this question is not crystal clear.
I am trying to find an efficient JQPL query in order to get all records of a complex object.
(ie. represented by multiple tables, with several one-to-many relationships - see simplified example below):
class ComplexObject {
private Set< SubOject1> so1 ...
.....
#OneToMany(fetch = FetchType.LAZY)
public Set< SubOject1>...
}
class SubObject1 {
private Set< SubOject2> so2 ...
.....
#OneToMany(fetch = FetchType.LAZY)
public Set< SubOject2>...
}
I am using the following JPQL query :
select distinct CO
from ComplexObject CO
left join fetch CO.so1 SO1
left join fetch SO1.so2
The query is run on a stateless session, in order to get a de facto snapshot of the current data in the DB, which is detached from the entity manager (hence the usage of left join fetch).
Unfortunately, I've encountered 2 problems :
Since the complex object contains multiple instances of so1, and each so1 instance contains multiple instances of so2, the underlying translation to SQL queries generates a specific select query per row of the product of all the table joins - a very wasteful solution. Is there a way to reduce the number of internal select queries? (This seems like the dreaded N+1 queries problem).
The JPQL query returns a ComplexObject instance per internal SQL query on the product of all the table joins - which means multiple references to the ComplexObject instances. Why does this happen on a 'select distinct' query?
The JPA framework I am using is hibernate, and the DB is HyperSQL.
The (1) issue turned out to be related to using the p6spy logging framework, which printed out all the results from a large DB table. The logging format led to an incorrect assumption that many queries where being executed.
While trying to fine tune performance, using native queries did not appear to have better performance then using JPQL queries.
Using a Native Query also resulted in Object typed results, which required post processing.
You can use View Objects to receive only the columns what you want:
StringBuilder sb = new StringBuilder();
sb.append(" SELECT new ").append(ObjectVO.class.getName()).append("(co.someInfo1, co.someInfo2, so1.someInfo )");
sb.append(" FROM ComplexObject co ");
sb.append(" JOIN co.subOject1s so1 ");
sb.append(" LEFT JOIN so1.so2 so2 ");
sb.append(" WHERE so1.id = :idSo1 AND so2 = :someThing");
Query q = em.createQuery(sb.toString());
q.setParameter("idSo1", idSo1);
q.setParameter("someThing", someThing);
List<ObjectVO> listResult = q.getResultList();
The ObjectVO class:
public class ObjectVO {
private String info1;
private Long info2;
private String info3;
public PedidoModel(String info1, Long info2, String info3){
this.info1 = info1;
this.info2 = info2;
this.info3 = info3;
}
}
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.
I have multiple tables with a lot of data in it. I'm only mentioning things pertinent to the question. For rendering data on the jsp, I only need selective data from different tables.
In reference to travel-vacation, lets say I have to retrieve and render holiday package name, itinerary duration and total price per defaults.
Holiday package name is in table HolidayPackage (id, name)
Itinerary duration in table Itinerary Itinerary (idPkg, idItinerary, dayNum) = (SUM aggregate of itinerary rows for a given package )
Price is defined in two different tables base price and total price
= (Sum( base(idPkg) + total(idPkg) ))
How can I retrieve selective data from these database tables to render the name, itinerary duration and total price for a given holiday package ?
I am using Hibernate with mysql as my database.
Thoughts:
Can I use a view to fetch data into my custom java object Result where Result is defined as:
class Result{
String name;
Intger itineraryDuration;
BigDecimal totalPrice;
}
Also, can I use functions as the definition of column values in views ?
What I do with views is I create an immutable hibernate model class and associated DAO to query the model class.
I annotate the model class as follows:
#Entity
#Immutable
#Table(name = "CLASSIFICATION_LABELS_V", schema = "CORPORATE")
I also set the setters to protected, but this is optional.
If the view is structured similar to an existing model class, you can use a named query and map it to your model using the resultClass attribute. The following is for Oracle so if using anything else, the query parameter would be different.
#NamedNativeQueries({
#NamedNativeQuery(name = "create_product_from_template", query = "call pkg_authoring.sp_create_prod_from_template(?, :productId, :templateId)", resultClass = TblProduct.class, callable = true)
})
In hibernate, you can use functions as follows:
#Formula(value = "(select fnHasProducts(customerId) from dual)")
#AccessType("property")
private Integer products = 0;
#Formula(value = "(select fnAssigneeForProduct(productId) from dual)")
private Integer assignee = 0;