I'm developing webapp using Spring & Hibernate.
Table 1: BaseTable
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| Id | bigint(20) | NO | PRI | | auto_increment |
| Serial1 | varchar(255) | YES | | NULL | |
| Serial2 | varchar(255) | YES | | NULL | |
| ModelNum | varchar(255) | YES | | NULL | |
| ... | .... | .. | 0 | | |
+------------+--------------+------+-----+---------+----------------+
Table 2: DetailTable
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| Id1 | varchar(20) | NO | PRI | | |
| Id2 | varchar(20) | NO | PRI | | |
| Id3 | varchar(20) | NO | PRI | | |
| Serial | varchar(255) | YES | | NULL | |
| ... | .... | .. | 0 | | |
+------------+--------------+------+-----+---------+----------------+
I need join the tables based on serials. The Serial
in Table2
may contain values from either Serial1
or Serial2
from Table1
so it should compare like an OR operator. I'm using hbm.xml for tables. No annotation mapping. I've joined tables like:
<one-to-one name="notes"
class="Notes" entity-name="Notes">
</one-to-one>
I was using this Query before:
SELECT A.* FROM Table2 As a INNER JOIN Table1 As b
ON (a.Serial = b.Serial1 or a.Serial = b.Serial2);
I went through this http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/associations.html but only 1 key column is being used.
How do I join using HBM.XML for this scenario? Is it possible?
Join statements are used when one wants to fetch data from multiple tables of database. Hibernate provides support for join statements where one can write single query to fetch data from multiple tables easily.
When a join table is used in mapping a relationship with an embeddable class on the owning side of the relationship, the containing entity rather than the embeddable class is considered the owner of the relationship. If the JoinTable annotation is missing, the default values of the annotation elements apply.
The referencedColumnName attribute tells Hibernate the name of the database column it shall use as the foreign key. There is one small thing left before you can use this association. You need to make sure, that the referenced entity implements Serializable.
Solution 1
Create a database view on the Table1
which exposes foreign key referencing Table2
. Project the foreign key from your posted query which you will use for the view anyway. Then map your entity to the view.
Solution 2
Use join formula:
For example, in the entity mapped to Table1
define the many-to-one association with the entity mapped to Table2
(seems to be your use case):
@ManyToOne
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula=@JoinFormula(value="(SELECT t2.serial FROM Table2 t2 WHERE serial1 = t2.serial OR serial2 = t2.serial)", referencedColumnName="serial"))
})
private Entity2 entity2;
However, join formulas seem to be very fragile in Hibernate for the time being (I managed to make this work only for many-to-one association and I had to make Entity2
implement Serializable
; otherwise it did not work and threw some strange NullPointer-
and ClassCastException
s).
You need to use native query for this purpose
String sql = "SELECT A.* FROM Table2 As a INNER JOIN Table1 As b "
+ " ON (a.Serial = b.Serial1 or a.Serial = b.Serial2);";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Table2.class);
List<Table2> tableContent = query.list();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With