Hibernate query inner join on unmapped table (unidirectional) - java

I do have a problem query problem with spring and hibernate.
I've got a class called Car which maps ManyToMany to my class Inventory. Inventory btw holds no references to the Car class.
This causes spring and hibernate to create the mapping table car_loading with a fk to the car and a fk to the inventory table.
I now want to query the inventory for a special car:
String squery = "SELECT i from Inventory i, car_loading loads WHERE i.id = loads.loading AND car = ?";
But I am getting the exception
org.hibernate.hql.ast.QuerySyntaxException: car_loading is not mapped
FYI: Hibernate doesn't support the JOIN ON x.a = y.b leading me to do it that way...
Thanks inn advance for any help!
EDIT - My Mapping
public class Car {
#OneToOne
private Driver driver;
#ManyToMany(cascade=CascadeType.ALL)
private List<Inventory> loading = new ArrayList<Inventory>();
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern="dd:MM:yyy HH:mm")
private Date lastModified;
//...
}
public class Inventory {
private Integer shouldAmount;
private Integer minAmount;
private Integer isAmount;
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern="dd:MM:yyy HH:mm")
private Date lastModified;
//..
}

You should never use the mapping table explicitly, hibernate adds it automatically when you use entity's properties.
For your situation the query should look like:
"select c.loading from Car c where c = ?"
or just get a car object Car car = session.get(Car.class, id), then use getter as ususal Collection<Inventory> loading = car.getLoading();

I saw this question and wanted to updated it. I did it the wrong way around. I could simply query the car and return all inventorys within this car. Because there is a relation from car to inventory, but not the other way around. So query a specific car and simply return the inventory list attribute did it for me...

Related

Hibernate entity join substitute value2 when value1 NULL

I am using Hibernate and trying to build the next logic in my entity for SELECT query. Creating a join column where if value of professor's name = NULL, then select value of teacher's name.
Code for Teacher table:
#Entity
#Table(name = "teacher")
public class Teacher {
#Id
#Column(name = "id_number)
private String id;
#OneToOne
#JoinColumn(name = "t_name")
private Professor name;
// Getters and Setters ...
}
Code for Professor table:
#Entity
#Table(name = "professor")
public class Professor{
#Id
#Column(name = "id_number)
private String id;
#Column(name = "p_name")
private String name;
// Getters and Setters ...
}
Working SQL query example:
select
t.id_number as "Identification Number",
isnull(p.p_name, t.t_name) as "Name"
from teacher t
left join professor p
on t.t_name = p.p_name
where id_number in (23, 24, 25, 26, 27)
What should I change in my entities to replicate logic of the SQL query above? Will really appreciate for any help provided.
I'm not sure if you can provide an annotation at field (name) level to achieve this. My guess is, if something like that is present then it might cause the update also to behave the same way. (override teacher's name with professor's)
Couple of other solutions:
Hibernate's Formula annotation:
Create another variable say actualName and provide Formula Annotation with Coalesce ( I used it before to return another field when one field was null).
#Formula("COALESCE(nullableField, backupField)")
I'm not sure if you can use a mapped entity in it, if not you've to make use of JoinColumnOrFormula annotation and write a query for this.
Create a getter for this new field actualName which will check if professor's name is present then return it. else return teacher's name. This will eliminate the need to write another query.
You could also modify the getter of name field in teacher class to return another field that you would want. NOTE: This will also cause your update operation on teacher's table to replace teacher's name with professor's if professor's name is present. Not Recommended at all

Hibernate criteria using left join to filter results

JSF application with hibernate
Is there a way to use a join to filter the results returned by criteria list?
Example: i have 2 tables. orders and customers.
#Entity(name = "order")
public class Order
{
#Id
private int id;
private String billingCustomerId;
private String shippingCustomerId;
private Date orderDate;
....
}
#Entity(name = "customer")
public class Customer
{
#Id
private String id;
private String name;
private String emailAddress
....
}
I need to return all orders for customers that are missing an email address and all orders that the order.billingCustomerId = null and order.shippingCustomerId = null.
The customer could match on the billingCustomerId or shippingCustomerId.
The SQL I would use
select o.* from order as o
LEFT join customer as c1 on o.billingCustomerId = c1.id
LEFT join customer as c2 on o.shippingCustomerId= c2.id
where (o.billingCustomerId is null and o.shippingCustomerId is null) or
(o.billingCustomerId is not null and c1.emailAddress is null) or
(o.shippingCustomerIdis not null and c2.emailAddress is null)
Hibernate Criteria
Criteria criteria1 = session.createCriteria(Order.class);
criteria.add(Restrictions.and(Restrictions.isNull("billingCustomerId"),
Restrictions.isNull("shippingCustomerId"));
List<Order> = criteria.list();
This will return the list of orders that billing /shipping customer = null.
How can i change the criteria to also include the orders for customers with missing email addresses?
Disjunction disjunciton = Restrictions.disjunction();
Criteria criteria = session.createCriteria(Order.class);
disjunciton.add(Restrictions.and(Restrictions.isNull("billingCustomerId"),
Restrictions.isNull("shippingCustomerId")));
disjunciton.add(...
...)
criteria.add(disjunciton);
List<Order> = criteria.list();
I have not been able to find examples of joining on a column, but only where the table have a common key.
I asked this question: Hibernate trouble getting composite key to work and discovered Hibernate can only create a join on columns that were created by relating 2 objects. I am going to add more to my answer to give more useful information but the best alternative you your case is to do a Session.createSQLQuery() using the query you showed above. Then before running the query put Query.addEntity(Order.class).addEntity(Customer.class). As long as your query returns the correct rows to fill out the Java objects correctly, Hibernate can populate them automatically. If that doesn't work you can still retrieve the data and populate it manually yourself.

Native Query (JPA ) not reset and return the same old result

I have a native sql query as the following :
for (init i=0; i<=2 ; i++) {
String sql = "Select * from accounts where id = ?";
Query query = em.createNativeQuery(sql,AccountBean.class);
query.setParameter(1, i );
AccountBean accountBean = (AccountBean)query.getSingleResult();
}
For the first loop it works correctly but any loop after the first one returns the same result as the first one , i debug it, the parameter changed , it works correctly if i change
Query query = em.createNativeQuery(sql,AccountBean.class);
to
Query query = em.createNativeQuery(queryString);
Regards
Wish79
Every JPA entity must have a primary key. Your JPA entities may not properly reflect the primary key, if any, on the database table.
I ran into the same problem. In my model class I had only one class variable annotated with #Id. However, that was not an accurate reflection of the table itself, which has a composite primary key. Thus, my query results returned the correct number of rows, but each confoundingly contained the same values, even though the actual data was different in the db. For example, this query:
Query query = entityManager.createQuery
("SELECT tbl FROM Tbl tbl WHERE tbl.id = 100
and tbl.code in ('A','B','C')");
...returned 10 rows, each showing a code of 'A'. But in actuality 9 of those 10 rows had a different code value ('B' or 'C'). It seemed as if the results were being cached and/or the tbl.code predicate was ignored. (That happened whether I used JPQL or Native SQL.) Very confusing.
To fix this I added an additional #Id annotation to my model to reflect the composite primary key:
#Id
#Column(name = "Code")
public String getCode() {
return this.code;
}
Now the query returns the data correctly and the code select criteria is no longer effectively ignored.
Edit: Although the above worked for me, on further research it seems a better approach to configure a separate JPA Entity composite primary key class. See http://docs.oracle.com/cd/E16439_01/doc.1013/e13981/cmp30cfg001.htm.
For example, here's an Entity class with an embedded primary key (see #EmbeddedId):
/**
* The persistent class for the SOME_TABLE database table.
*/
#Entity
#Table(name = "SOME_TABLE")
public class SomeTable implements Serializable {
#EmbeddedId
private SomeTablePk id;
#Column(name = "NUMBER_HRS")
private BigDecimal numberHrs;
...
...and here's the composite primary key class (see #Embeddable):
#Embeddable
public class SomeTablePk implements Serializable {
#Column(name = "SOME_ID")
private String someId;
#Column(name = "ANOTHER_ID")
private BigDecimal anotherId;
public String getSomeId() {
return someId;
}
...

JPA : Is there any way to run a simple SELECT statement that only access a few columns?

I'm new to JPA so forgive me if my question seems silly.
We have used JPA in our project. I see that every entity object has a direct mapping with a table and each row in the table is an object of that entity type.
But, suppose I only want to access one or two columns of a table, how do i go about doing it ? The reason I'm asking is because of the task i have in hand.
There are two tables. The first table has everything set up with JPA so that each row can be cast into an object type. The first table has a column that is referenced in the second table i.e. say, table A has column CLOTH_ID and Table B has columns CLOTH_ID and CLOTH_DESCRIPTION. CLOTH_ID is used in both Table A and B; But B has the CLOTH_DESCRIPTION columns which corresponds to CLOTH_ID.
I'm displaying Table A in my webpage but I also need to display : CLOTH_DESCRIPTION in my webpage. Is there a JPA oriented way to do this or Am i better off using regular JDBC to extract the CLOTH DESCRIPTION values ?
I assume you have the following setup:
#Entity
#Table(name="A")
class A {
#ManyToOne
#JoinColumn(name="CLOTH_ID")
private B cloth;
//...
}
#Entity
#Table(name="B")
class B {
#Id
#Column(name="CLOTH_ID")
private int id;
#Column(name="CLOTH_DESCRIPTION")
private String description;
//...
}
If you don't... you're doing it wrong (i.e. it is not idiomatic JPA usage). You have the following options:
Simply fetch A
In this case #ManyToOne relationship will be fetched eagerly by default as well. Then simply call in Java:
a.getCloth().getDescription()
Prefer this approach as it is the simplest and most idiomatic unless the number of columns in B is huge.
Use JPA query with custom columns:
SELECT a, a.b.description
FROM A a
WHERE a.id = :id
In this case the query returns List<Object[]>, where Object[] actually contains two elements: A and String.
Same as above but with custom DTO:
class Adto {
private final A a;
private final String description;
public Adto(A a, String description) {
this.a = a;
this.description = description;
}
}
And slightly modified query:
SELECT new Adto(a, a.b.description)
FROM A a
WHERE a.id = :id

Basic Hibernate/JPA Mapping question

I have to tables I want to map to each other.
I want to populate 2 drop down lists: code_r and code_l.
When i choose a value from code_r, code_l should display only certain records.
In my database I have 2 tables:
Table code_r
===================
CODE INT
LIBELLE VARCHAR
And
Table code_l
===================
ID BIGINT
CODE_R_ID INT
LIBELLE VARCHAR
One code_r can have multiple code_l associated with it (based on the code_r_id (not a defined as a Foreign key in the code_l definition). Of course, a code_l can only be associated to one code_r.
The following SQL query works fine:
SELECT *
FROM code_r r
left join `code_l` l on l.code_r_id = r.code;
How should I implement that using using JPA/Hibernate-3.5 annotations in the CodeR and CodeL classes??
Any help would be appreciated. Thanks in advance.
With Hibernate (and now standardized in JPA 2.0), you can use a unidirectional one-to-many association without a join table using a JoinColumn annotation:
Annotate the CodeR like this:
#Entity
public class CodeR {
#Id
private Integer code;
private String libelle;
#OneToMany
#JoinColumn(name="CODE_R_ID")
Set<CodeL> codeLs = new HashSet<CodeL>():
// getters, setters
}
And CodeL
#Entity
public class CodeL {
#Id
private Integer id;
private String libelle;
// getters, setters, equals, hashCode
}
And the JPQL query:
SELECT r FROM CodeR LEFT JOIN r.codeLs
in the CodeR class:
#OneToMany(mappedBy="code_r_id")
Collection elementsFromL;
in the CodeL class:
#ManyToOne
CodeR code_r_id;

Categories

Resources