Hibernate SQL Error in generated query (Potentially a mapping mistake) - java

I'm making this simple app using Hibernate to do some CRUD operations. I'm having this error in the query generated by hibernate
Config XML:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/library</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.default_schema">library</property>
<property name="hbm2ddl.auto" value="create"/>
<!-- Mappings -->
<mapping resource="librarysystem/mappings/Role.hbm.xml"/>
<mapping resource="librarysystem/mappings/Librarian.hbm.xml"/>
<mapping resource="librarysystem/mappings/Task.hbm.xml"/>
<mapping resource="librarysystem/mappings/Library.hbm.xml"/>
</session-factory>
</hibernate-configuration>
POJO:
public class Library implements java.io.Serializable {
private int id;
private String name;
private Set librarians = new HashSet(0);
//Constructors, getters and setters...
}
Mapping:
<hibernate-mapping>
<class name="librarysystem.entities.Library" table="library" catalog="library" optimistic-lock="version">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="name" length="45" />
</property>
<set name="librarians" table="librarian" inverse="true" lazy="true" fetch="select">
<key>
<column name="libraryid" not-null="true" />
</key>
<one-to-many class="librarysystem.entities.Librarian" />
</set>
</class>
</hibernate-mapping>
Code to get the list:
List<Library> libraries = session.createQuery("FROM Library").list();
When I run a query to get the list of libraries, an exception occurs saying that the query syntax is wrong
the log output of the query is:
select
library0_.id as id1_2_,
library0_.name as name2_2_
from
library.library.library library0_
How did the library.library.library happened?
Any help please?
I've given the minimum details as I thought was necessary. If you need more code to find the error (like other POJOs and mappings), please inform me

How did the library.library.library happened? Any help please?
I'm no expert here but I think the tripple library here comes from the table being named library within a Database (catalog) named library.
<class name="librarysystem.entities.Library" table="library" catalog="library" optimistic-lock="version">
The table name and the catalog name are the same. So we are looking for a catalog called library library within which we want a table called library library.library. Although I'm not 100% on the third library, I think I'm in the right direction.
On a side note, I find it easier to work with hibernate annotation instead of xml mapping.
Difference between annotation and xml mapping in Hibernate
XML mapping example
Annotation example

Related

Generating DDL from hibernate mapping file

The following hibernate mapping file generates the java class and the DEPARTMENT table as expected but it doesn't create the DPT_TEACHERS table in the DB, why not ?
<hibernate-mapping>
<class name="hibernate.Department" table="DEPARTMENT">
<id name="id" column="ID">
<generator class="native"/>
</id>
<property name="subject" column="SUBJECT" type="string"/>
<set name="teachers" table="DPT_TEACHERS">
<key column="ID"/>
<one-to-many class="hibernate.Teacher"/>
</set>
</class>
</hibernate-mapping>
You need to add property
hibernate.hbm2ddl.auto
with your database connection properties in your hibernate.cfg.xml to create schema automatically.
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/Test?createDatabaseIfNotExist=true</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
table="DPT_TEACHERS" is not required. There is no need for another table to create a 1:N relationship. key column="ID" is confusing, it should be key column="TEACHER_ID" so it can be added in Teacher table as a 1:N relationship

Hibernate - org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped

I'm new to hibernate and I'm trying to solve some problems i cannot understand too well...
For example, I have this query
Query query = session.createQuery("from Client where clientId = "+clientId+")");
List result = query.list();
My Client.hbm.xml is
<class name="it.besmart.models.Client" table="client" catalog="SMARTPARK">
<id name="idClient" type="int">
<column name="id_client" />
<generator class="identity" />
</id>
<property name="nomeClient" type="string">
<column name="nome_client" length="65535" not-null="true" />
</property>
<property name="numPosti" type="int">
<column name="num_posti" not-null="true" />
</property>
<property name="numLuci" type="int">
<column name="num_luci" not-null="true" />
</property>
<property name="inizioPosti" type="int">
<column name="inizio_posti" not-null="true" />
</property>
<property name="inizioLuci" type="int">
<column name="inizio_luci" not-null="true" />
</property>
</class>
</hibernate-mapping>
The table on the DB is called client and the column is client_id
The mapping in hibernate.cfg.xml is
<hibernate-configuration>
<session-factory name="parkserver">
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">passwprd</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.3.67:3306/SMARTPARK</property>
<property name="hibernate.connection.username">parkuser</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="it.besmart.models.Client" resource="Client.hbm.xml"/>
<mapping class="it.besmart.models.Illuminazione" resource="Illuminazione.hbm.xml"/>
<mapping class="it.besmart.models.MappaPosti" resource="MappaPosti.hbm.xml"/>
<mapping class="it.besmart.models.Occupazione" resource="Occupazione.hbm.xml"/>
</session-factory>
</hibernate-configuration>
I'm having no problems in another query in the application, but when i try to executer the SELECT query i got this exception
org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped [from Client where clientId = 1)]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:79)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:218)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:298)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
at it.besmart.parkserver.SocketClientHandler.run(SocketClientHandler.java:83)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:76)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:321)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3678)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190)
I don't know why Client is not mapped, it's correctly in the cfg file...
Thanks in advance
Try to add the full name of the class in the query:
Query query = session.createQuery("from it.besmart.models.Client where clientId = :c");
query.setString("c", clientId)
List result = query.list();
I also changed to late binding here which is preferable but has nothing to do with your problem.
As Maurice Perry pointed out in comment below:
- You can also specify the default package in the mapping file: <hibernate-mapping package="it.besmart.models">

Hibernate configuration file (.cfg.xml) for mapping multiple MySQL tables in the same database?

I am experimenting with Hibernate for my Java web app. The following is part of my hibernate.cfg.xml, and I wondering how to map multiple database tables in the same configuration file. I use annotations to map my models to mysql database table, and I have multiple model classes (for example: models.Book), how to map the models in hibernate.cfg.xml?
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test_db</property>
<property name="connection.username">root</property>
<property name="connection.password">xxx</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<mapping class ="models.Category" />
</session-factory>
</hibernate-configuration>
We should not specify mappings in cfg.xml file. It has to be done by either annotations or XML.
For Annotations:
The cfg.xml file that is provided by you looks ok, if we are using the annotations to indicate database mappings with entity classes.
To use XML way of mapping between Entities and Tables, an hbm.xml file needs to be created and in that case, Replace
<mapping class ="models.Category" />
with something like
<mapping resource="models/Book.hbm.xml></mapping>
and hbm.xml file contains the necessary mapping as follows.
for example:
<hibernate-mapping>
<class name="models.Book" table="Book" catalog="your database name">
<id name="bookId" type="java.lang.Integer">
<column name="BOOKID" />
<generator class="identity" />
</id>
<property name="authorName" type="string">
<column name="AUTHOR_NAME" length="10" not-null="true" unique="true" />
</property>
</class>//all the database mappings
</hibernate-mapping>
Sorry, if I understand your question wrongly.
WE can't configure the multiple databases in single configuration file.if we use multiple databases we have to use multiple configuration file. in respective tables we can configure in respective configuration file.

Table missing error while maaping MySQL view to hibernate

I am trying to map a MySql view to hibernate. But when I am getting and Table missing error while starting the application.
view is
CREATE
ALGORITHM = UNDEFINED
DEFINER = `mydbadmin`#`%`
SQL SECURITY DEFINER
VIEW `Reservation_Transaction_view` AS
select
convert( concat(`apst`.`Tid`,
_utf8'-',
`apst`.`RoomIndex`,
_utf8'-',
`apst`.`Rid`) using utf8) AS `id`,
`apst`.`Tid` AS `transactionId`,
`apst`.`RoomIndex` AS `room no`,
`apst`.`Pid` AS `paymentId`,
`apst`.`Rid` AS `reservationId`
from
`agent_payment_sub_transaction` `apst`
where
(`apst`.`Rid` <> 0)
group by `apst`.`Tid` , `apst`.`RoomIndex`
The mapping
<?xml version="1.0"?>
<hibernate-mapping>
<class name="com.abc.def.entity.ReservationTransactionView"
table="Reservation_Transaction_view" catalog="abcd">
<id name="id" type="string" />
<property name="transactionId" type="java.lang.Integer">
<column name="transactionId" />
</property>
<property name="roomNo" type="java.lang.Integer">
<column name="`room no`" />
</property>
<property name="paymentId" type="java.lang.Integer">
<column name="paymentId" />
</property>
<property name="reservationId" type="java.lang.Integer">
<column name="reservationId" />
</property>
The error is as followed.
org.hibernate.HibernateException: Missing table: Reservation_Transaction_view
I am using MySQL and Hibernate3.0 Please Help me for this query.
Thanks in advance.

Issue with Eclipse Hibernate Tools

I'm trying to use the Hibernate Code Generation feature in Hibernate Tools Eclipse Add-On. It is giving me the following error:
org.hibernate.InvalidMappingException: Could not parse mapping document from resource Alert.hbm.xml
Could not parse mapping document from resource Alert.hbm.xml
org.hibernate.MappingException: class Alert not found while looking for property: alertId
class Alert not found while looking for property: alertId
org.hibernate.MappingException: class Alert not found while looking for property: alertId
class Alert not found while looking for property: alertId
java.lang.ClassNotFoundException: Alert
Alert
It is not finding the class Alert.java but I thought the Code Generator (hence the name...) was supposed to generate all the hibernate classes for me.
Using eclipse Indigo with Hibernate Tools 3.4.x.
Here's my hibernate.cfg.xml:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/findata?tcpKeepAlive=true
</property>
<property name="connection.username">root</property>
<property name="connection.password">madmax1.</property>
<property name="connection.pool_size">2</property>
<property name="show_sql">true</property>
<property name="dialect">
org.hibernate.dialect.mysqldialect
</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<mapping resource="Alert.hbm.xml" />
<mapping resource="Entity.hbm.xml" />
<mapping resource="FactData.hbm.xml" />
<mapping resource="TimeEvent.hbm.xml" />
<mapping resource="User.hbm.xml" />
<mapping resource="AlertTarget.hbm.xml" />
<mapping resource="LogAlert.hbm.xml" />
</session-factory>
</hibernate-configuration>
Here's Alert.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Alert" table="alerts">
<id name="alertId" column="id">
<generator class="assigned"/>
</id>
<property name="limitValue" column="limit_value" type="decimal" />
<!-- The unique=true property makes the many-to-one a one-to-one relationship -->
<many-to-one name="alertEntity"
class="Entity" column="entity_id"
not-null="true" cascade="all" unique="true"/>
<set name="alert_targets" table="alerts_alert_targets" cascade="all">
<key column="alert_id" />
<many-to-many column="alert_target_id"
class="AlertTarget" />
</set>
</class>
</hibernate-mapping>
weird it is looking for the to-be-generated class.
I will check the hibernate-reverse.xml file and check if it does not have additional attributes that may result in this.
Alternatively, during generation, try to setup the hibernate-revenge.xml and hibernate.cfg.xml rather than using the existing ones.
The cause turned out to be the fact that the "type" was not specified for the "id" property in Alert.hbm.xml.

Categories

Resources