Why this hibernate exception occurs,,, - java

I'm getting the exception like,
"Named Query mySp Not known"
The mapping file will be looking like this,
<hibernate-mapping>
<sql-query name="mySp">
<return-scalar column="count1" type="int" />
<return-scalar column="name" type="int" />
<return-scalar column="count2" type="int" />
{ call get_proc_sp :p1,p2,p3 }
</sql-query>
</hibernate-mapping>
My Procedure name is, get_proc_sp and it accepts three parameters, the parameter names are m1,m2,m3
This is the DAO code,
List<MyBean> list = sessionFactory.getCurrentSession()
.getNamedQuery("mySp")
.setParameter("m1", arg1)
.setParameter("m2", narg)
.setParameter("m3", arg5)
.setResultTransformer(Transformers.aliasToBean(MyBean.class))
.list();

One likely reason is that the hbm file in which you are defining the query is not registered with the sessionFactory.

Related

Hibernate View showing different results in app and Workbench

I'm working on an app in Java connected to a MySql database by hibernate.
I'm using Pojos to define the classes and using the class Session to connect to the database.
The problem is the next view:
CREATE OR REPLACE VIEW INVENTARIO AS
SELECT
ID_ARTICULO,
ID_ESTRUCTURA,
ID_ESTRUCTURA_ORIGEN,
SUM(STOCK)STOCK,
STOCK_MIN,
NECESITA_REPO
FROM
HISTORICO_INVENTARIO
LEFT JOIN TIPOS_MOVIMIENTO
ON HISTORICO_INVENTARIO.ID_TIPO_MOV = TIPOS_MOVIMIENTO.ID_TIPO_MOV
GROUP BY ID_ARTICULO , ID_ESTRUCTURA , ID_ESTRUCTURA_ORIGEN , STOCK_MIN , NECESITA_REPO;
In Java, i'm mapping the view this way:
<hibernate-mapping>
<class name="Pojos.Inventario" table="INVENTARIO">
<id name="id_articulo" type="string" column="ID_ARTICULO"/>
<property name="id_estructura" type="string" column="ID_ESTRUCTURA" />
<property name="id_estructura_origen" type="string" column="ID_ESTRUCTURA_ORIGEN" />
<property name="stock" type="float" column="STOCK" />
<property name="stock_min" type="float" column="STOCK_MIN" />
<property name="necesita_repo" type="string" column="NECESITA_REPO" />
</class>
I've to say that the field "id_articulo" is not the ID, but i've to choose one because.
If i execute this view in MySql Workbench i can the the results correctly. If i execute the same query in my app, i'm having different results.
Does anyone knows why could be this happening?
Thanks in advance.
EDIT:
I've tried to define the XML putting the SQL in the subselect tag:
<class name="Pojos.Inventario">
<subselect>
SELECT
ID_ARTICULO,
ID_ESTRUCTURA,
ID_ESTRUCTURA_ORIGEN,
SUM(STOCK) STOCK,
STOCK_MIN,
NECESITA_REPO
FROM
HISTORICO_INVENTARIO
LEFT JOIN TIPOS_MOVIMIENTO
ON HISTORICO_INVENTARIO.ID_TIPO_MOV = TIPOS_MOVIMIENTO.ID_TIPO_MOV
GROUP BY ID_ARTICULO , ID_ESTRUCTURA , ID_ESTRUCTURA_ORIGEN , STOCK_MIN , NECESITA_REPO
</subselect>
<synchronize table="HISTORICO_INVENTARIO"/>
<synchronize table="TIPOS_MOVIMIENTO"/>
<id name="id_articulo" type="string" column="ID_ARTICULO"/>
<property name="id_estructura" type="string" column="ID_ESTRUCTURA" />
<property name="id_estructura_origen" type="string" column="ID_ESTRUCTURA_ORIGEN" />
<property name="stock" type="float" column="STOCK" />
<property name="stock_min" type="float" column="STOCK_MIN" />
<property name="necesita_repo" type="string" column="NECESITA_REPO" />
</class>
Getting the worong resultset
make your hibernate show_sql parameter to true. Now try to capture sql in your log and try to run it in your sql workbench.
<property name="show_sql">true</property>
Done it!
The problem was produced by the ID. I've added one extra field wich is the new ID. Now I'm getting the correct resultset

How to insert constant value in a join table with Hibernate in a many-to-many relation?

I have a mapping like A - AB - B but the AB table is also a join table for other tables (yeah, thanks, no comment :p). In the AB table, I have a CODE (non-null) column.
I can fetch the correct datas by adding a where tag in the mapping, but when I insert values, Hibernate does not add the value in the CODE column... Well, I don't know how to tell Hibernate to do that.
Here is the mapping of the A table to get a Set:
<set name="b" table="AB" lazy="false" where="CODE='1.2.3'">
<key column="A_ID" />
<many-to-many column="B_ID" class="B">
</many-to-many>
</set>
Hibernate create an insert with only the A_ID and the B_ID values, I'd like to tell Hibernate to insert CODE='1.2.3' in its SQL INSERT query.
Many thanks for your help,
UPDATE
The idea in a Java point of view is to have a signature like this in A: getB():Set<B> I do not want getAB():Set<AB>.
Thanks
for AB use two classes one for IDs ABIdClass(A_ID,B_ID) and the other for Code(and all extra columns) ABClass(CODE) and use default attribute of column for constant value:
<class name="ABClass" table="AB">
<composite-id name="id" class="ABIdClass">
<key-many-to-one name="a" class="A" column="a_id" />
<key-many-to-one name="b" class="B" column="b_id" />
</composite-id>
<property name="code" type="string">
<column name="code" not-null="false" default="1.2.3" />
<property/>
</class>
you can also try something like this:
ABIdClass abId = new ABIdClass();
abId.setA(a);
abId.setB(b);
ABClass ab = new ABClass();
ab.setId(abId);
ab.setCode("1.2.3");
a.getABClass().add(ab);
hope these be useful.
You should be able to achieve what you are looking for using the Hibernate Table per Class Hierarchy approach.
abstract class Mapping { private String code; }
class TableA {}
class TableB {}
class TableAB extends Mapping { private TableA a; private TableB b; }
class TableC {}
class TableD {}
class TableCD extends Mapping { private TableC c; private TableD d; }
class TableE {}
class TableF {}
class TableEF extends Mapping { private TableE e; private TableF f; }
<class name="TableA" table="tableA"/>
<class name="TableB" table="tableB"/>
<class name="TableC" table="tableC"/>
<class name="TableD" table="tableD"/>
<class name="TableE" table="tableE"/>
<class name="TableF" table="tableF"/>
<class name="Mapping" table="mapping">
<discriminator column="CODE" type="string"/>
<subclass name="TableAB" discriminator-value="1.2.3">
<property name="a" column="a_id"/>
<property name="b" column="b_id"/>
</subclass>
<subclass name="TableCD" discriminator-value="4.5.6">
<property name="c" column="a_id"/>
<property name="d" column="b_id"/>
</subclass>
<subclass name="TableEF" discriminator-value="7.8.9">
<property name="e" column="a_id"/>
<property name="f" column="b_id"/>
</subclass>
</class>
Note that the columns a_id and b_id are common for all relationships. This will ensure that a single mapping table can be used for different relationships as you want.

Map hibernate many-to-one with the foreign key in subclass joined table

I'm mapping some entities using Hibernate 3 for my project and simply explained I've got kind of this:
Student entity (tstudent table)
UniversityStudent entity (tuniversitystudent table)
University entity (tuniversity table)
UniversityStudent extends from Student and has its own attributes, like the university itself, which is a foreign key into the tuniversitystudent table. It is also mapped like a subclass into the Student class, using a discriminator field:
<class name="mycompany.Student" table="tstudent" discriminator-value="BASIC">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<discriminator column="type" />
<property name="name" column="name" />
<property name="surname" column="surname" />
<property name="phoneNumber" column="phone_number" />
<subclass discriminator-value="UNIVERSITY"
name="mycompany.UniversityStudent">
<join table="tuniversitystudent">
<key column="id_student" />
<many-to-one name="university" class="mycompany.University">
<column name="id_university" />
</many-to-one>
</join>
</subclass>
</class>
Well, now I want to have a Set collection with the UniversityStudent entities for each University. So I map it like that:
<class name="mycompany.University" table="tuniversity">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" />
<set name="universityStudents" table="tuniversitystudent">
<key>
<column name="id_university" />
</key>
<one-to-many class="mycompany.UniversityStudent" />
</set>
</class>
My problem comes when I want to load a University object, Hibernate complains that id_university doesn't exist in tstudent table. I checked the generated SQL query and it really tries to load it from tstudent.
Unknown column 'student0_.id_university' in 'field list'
It seems that it's recognizing that it is a subclass of the basic Student and tries to join the collection using a field in the parent table, but however the field is actually in the child table, because only university students can have a University assigned.
I tried another workaround which seems to work but it's not valid for me, that's mapping the UniversityStudent as a joined-subclass instead of a subclass with a join inside:
<joined-subclass name="mycompany.UniversityStudent" table="tuniversitystudent">
<key column="id_student" />
<many-to-one name="university" class="mycompany.University">
<column name="id_university" />
</many-to-one>
</joined-subclass>
However, I'm interested in keeping it as a subclass with a discriminator value. Any idea?
I checked out some resources and finally got into this bug: https://hibernate.atlassian.net/browse/HHH-1015, which looks absolutely compatible with your case. Checkout this old question as well, again very similar to your case.
I firstly read the definition of table per sublass given by Hibernate (I know, it is for version 3.3 but I couldn't find the same source for Hibernate 4): joined-subclass seems (to me) to be a custom implementation of subclass using a discriminator provided by Hibernate and that is a good reason to stay away from its usage. However, from what I know, the mappings table per sublass and table per subclass using a discriminator should be equivalent, that's why I believe the bug I pointed you out is really still open.
If you have time and will, you can try to use another JPA provider and check if you still run in the same issue. JPA 2.0 specifications is a thing, provider implementation is another! I recently run into another bug (related to #IdClass) which forced me to try EclipseLink and the configuration which was not working with Hibernate was right with Eclipse Link
Seems you can use Custom SQL (or HQL) for loading. Haven't tried it myself, but looks like, hmm, at least as a last resort, it provides a decent solution.
Define the query in your HBM:
<sql-query name="universityStudents">
<load-collection alias="unistu" role="University.universityStudents"/>
SELECT unistu.*, student.*
FROM tuniversitystudent unistu
JOIN tstudent student
ON unistu.id_student = student.id
WHERE unistu.id_university = :id
</sql-query>
And then use it inside University:
<set name="universityStudents" inverse="true">
<key/>
<one-to-many class="mycompany.UniversityStudent"/>
<loader query-ref="universityStudents"/>
</set>

basic Hibernate setup question: why is this resulting in one million null objects?

I have two tables: foo (primary key: foo_id) and foo_entry (primary key: foo_entry_id; foreign key: foo_id).
Below is my Hibernate config.
My problem is, when I call getAttributes() on the FooModel class, I end up with a list of a little over one million null objects. (foo table has ~200 rows, foo_entry has ~10,000).
I'm new to Hibernate and suspect I am just overlooking or am just not understanding something very, very basic. Any help appreciated!
<hibernate-mapping package="com.blah.www">
<class name="FooModel" table="foo">
<id name="fooId" column="foo_id"></id>
<list name="attributes" table="foo_entry">
<key column="foo_id" />
<index column="entry_id" />
<one-to-many class="FooEntryModel" />
</list>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.blah.www">
<class name="FooEntryModel" table="foo_entry">
<id name="fooEntryId" column="foo_entry_id">
<generator class="native" />
</id>
<property name="fooId" type="int" column="foo_id" />
<property name="attrName" type="string" column="attr_name" />
<property name="attrValue" type="string" column="attr_value" />
<property name="startDate" type="timestamp" column="start_date" />
<property name="endDate" type="timestamp" column="end_date" />
</class>
</hibernate-mapping>
The numbers imply you're getting a Cartesian join. Do you have the FK set up in the database?
aside - I used Hibernate for a a year and never coded an attribute-infused model or one of those files like your show. We always reverse-engineered the database.
First step to debug is to see the query, Hibernate generated for you, in the logs. However, I suggest you to try this,
<list name="attributes">
<key column="foo_id" />
<one-to-many class="FooEntryModel" />
</list>
Sigh...
This turned out to have a very logical (and very subtle) explanation.
I had misunderstood and hijacked the semantics of the <index> (also known as <list-index>) tag within <list>. Namely, given:
<list name="attributes">
<key column="foo_id" />
<index column="some_integer_value" />
<one-to-many class="FooEntryModel" />
</list>
... I thought was referring to the attribute by which you want to order the list. In fact, it refers to an attribute whose value denotes at what index position within the list to insert the overall object. It's meant to be a placeholder attribute, maintained and used entirely by Hibernate.
The value of the "some_integer_value" to which I was mapping varied in my test data. Sometimes the value was less than a 100. Sometimes it was greater than a million.
Thus, upon mapping just one row where "some_integer_value" == e.g. 100,001, Hibernate would create a list with that object inserted in the 100,001st position. Every list member preceding it, naturally, would be null.

Legacy mapping with hibernate

For my current project I have to map a legacy database using hibernate, but I'm running into some problems.
The database is setup using one 'entity' table, which contains common properties for all domain objects. Properties include (among others) creation date, owner (user), and a primary key which is subsequently used in the tables for the domain objects.
A simple representation of the context is as such:
table entity
- int id
- varchar owner
table account
- int accountid (references entity.id)
table contact
- int contactid (references entity.id)
- int accountid (references account.accountid)
My problem exhibits itself when I try to add a collection mapping to my account mapping, containing all contacts belonging to the account. My attempts boil down to the following:
<hibernate-mapping>
<class name="Contact" table="entity">
<id name="id" column="id">
<generator class="native" />
</id>
<join table="contact">
<key column="contactid"/>
<!-- more stuff -->
</join>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="Account" table="entity">
<id name="id" column="id">
<generator class="native" />
</id>
<bag name="contacts" table="contact">
<key column="accountid" />
<one-to-many class="Contact"/>
</bag>
<join table="account">
<key column="accountid"/>
<!-- more stuff -->
</join>
</class>
</hibernate-mapping>
However, when I try to fetch the account I get an SQL error, stating that the entity table does not contain a column called accountid. I see why this is happening: the mapping tries to find the accountid column in the entity table, when I want it to look in the contact table. Am I missing something obvious here, or should I approach this problem from another direction?
This looks to me like you actually need to be mapping an inheritance, using the Table Per Subclass paradigm.
Something like this:
<class name="entity" table="entity">
<id name="id" column="id">
...
</id>
<joined-subclass name="contact" table="contact">
<key column="contactid"/>
</joined-subclass>
<joined-subclass name="account" table="account">
<key column="accountid"/>
</joined-subclass>
</class>
That's approximate by the way - it's described in detail in section 9.1.2 of the Hibernate documentation (just in case you can't find it, it's called "Table per subclass").
Cheers
Rich

Categories