Ok, here it goes my question. I have a User POJO and a Media POJO, both mapped with a bidirectional (one-to-many / many-to-one) relationship. And when I try to retrieve the "UploadedMedia" from a returned user I get a strange Exception.
Hibernate version: 3.2
Mapping documents:
Code:
@User.hbm.xml
<hibernate-mapping auto-import="true" default-lazy="false">
<class name="com.mimetics.beans.User" table="users">
<id name="email" type="java.lang.String" column="email">
<generator class="native"/>
</id>
<property name="name" type="java.lang.String" column="name" not-null="true" length="45"/>
<property name="surname" type="java.lang.String" column="surname" not-null="true" length="45"/>
<property name="country" type="java.lang.String" column="country" not-null="true" length="255"/>
<property name="nickname" type="java.lang.String" column="nickname" not-null="true" length="45"/>
<property name="password" type="java.lang.String" column="password" not-null="true" length="12"/>
<many-to-one name="userPreferences" class="com.mimetics.beans.UserPreferences"
foreign-key="fk_user_user_preferences" column="preferences" not-null="true"/>
<many-to-one name="userType" class="com.mimetics.beans.UserType"
foreign-key="fk_user_user_types" column="type" not-null="true"/>
<!-- Collection Sets -->
<set name="uploadedMedia" inverse="true" lazy="true">
<key not-null="true" column="owner"/>
<one-to-many class="com.mimetics.beans.Media"/>
</set>
<!-- SENT & RECEIVED MESSAGES -->
<set name="sentMessages" table="messages" lazy="true" >
<key not-null="true" column="from"/>
<one-to-many class="com.mimetics.beans.Message"/>
</set>
<set name="receivedMessages" table="messages" lazy="true">
<key not-null="true" column="to"/>
<one-to-many class="com.mimetics.beans.Message"/>
</set>
<!-- POSTED COMMENTS -->
<set name="postedComments" lazy="true">
<key not-null="true" column="email"/>
<one-to-many class="com.mimetics.beans.Comment" />
</set>
</class>
</hibernate-mapping>
Code:
@Media.hbm.xml
<hibernate-mapping auto-import="true" default-lazy="false">
<!-- Indicamos la clase a persistir y la tabla a la que corresponde-->
<class name="com.mimetics.beans.Media" table="media">
<!-- Especificamos la clave primaria -->
<id name="mediaId" type="java.lang.Long" column="media_id">
<generator class="native"/>
</id>
<!-- A continuación el resto de atributos -->
<property name="fileName" type="java.lang.Long" column="filename" not-null="true"/>
<property name="size" type="java.lang.Long" column="file_size" not-null="true"/>
<property name="sizeMb" type="java.lang.Integer" column="file_size_mb" not-null="true"/>
<property name="path" type="java.lang.String" column="path" not-null="true" />
<property name="description" type="java.lang.String" column="description" not-null="false"/>
<property name="views" type="java.lang.Long" column="views" not-null="true" />
<property name="title" type="java.lang.String" column="title" not-null="false" />
<property name="tags" type="java.lang.String" column="tags" not-null="false" />
<property name="uploadDate" type="java.util.Date" column="upload_date" not-null="true"/>
<many-to-one name="mediaType" class="com.mimetics.beans.MediaType"
foreign-key="fk_media_media_types" column="type" not-null="true" />
<many-to-one name="owner" class="com.mimetics.beans.User"
foreign-key="fk_media_users" column="owner" not-null="true" insert="false" update="false"/>
<set name="receivedComments" lazy="true">
<key not-null="true" column="media_id"/>
<one-to-many class="com.mimetics.beans.Comment" />
</set>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():I use a "Manager" approach for getting the SessionFactory and a Session object, here are the clases:
Code:
public class Manager implements IManager
{
private Session session = null;
/**
* Creates a new instance of Manager
*/
public Manager (Session session)
{
this.session = session;
}
public Session getSession ()
{
return this.session;
}
public void begin ()
{
if (this.getSession () != null)
this.getSession ().beginTransaction ();
}
public void commit ()
{
if (this.getSession () != null)
this.getSession ().getTransaction ().commit ();
}
public void rollback ()
{
if (this.getSession () != null)
{
try
{
this.getSession ().getTransaction ().rollback ();
}
catch (HibernateException hbex2)
{
StringBuffer exception = new StringBuffer ("Couldn't do rollback(): ");
exception.append (hbex2.toString ());
System.out.println (exception.toString ());
}
try
{
this.getSession ().close ();
}
catch (HibernateException hbex3)
{
StringBuffer exception = new StringBuffer ("Error clossing session!: ");
exception.append (hbex3.toString ());
System.out.println (exception.toString ());
}
}
}
public void end ()
{
if (this.getSession () != null)
session.close ();
}
}
the MediaManager invokes the Manager class on it's constructor and then uses it's methods.
Code:
public class MediaManager extends Manager
{
private Session session;
/** Creates a new instance of MediaManager */
public MediaManager (Session session)
{
super (session);
}
public Media getMediaById (Long mediaId )
{
super.begin ();
Media media = (Media) this.session.get (Media.class, mediaId);
super.end ();
return media;
}
public Set getUserUploadedMedia ()
{
Set topTen = null;
Query hbQuery = null;
try
{
/*Try to do as many operations as possible in a single transaction*/
String queryString = new String ("from User usr where usr.email='xabier.burgos@gmail.com'");
super.begin ();
hbQuery = super.getSession ().createQuery (queryString);
User cybrid = (User) hbQuery.uniqueResult ();
topTen = cybrid.getUploadedMedia ();
super.commit ();
}
catch (QueryException queryEx)
{
System.out.println ("Error executing query: ");
queryEx.printStackTrace (System.out);
super.rollback ();
}
finally
{
super.end ();
}
return topTen;
}
}
Full stack trace of any exception that occurs:The could not execute batch update exception. Why is Hibernate trying to do an update when I'm just retrieving data?.
Code:
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
com.mimetics.managers.Manager.commit(Manager.java:43)
com.mimetics.managers.MediaManager.getTopTenMedia(MediaManager.java:50)
com.mimetics.actions.Setup.execute(Setup.java:53)
org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:53)
org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:64)
org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:48)
org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:280)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1858)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:446)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
Name and version of the database you are using: MySQL 5.0.27The generated SQL (show_sql=true):Code:
**** Initilizing HibernatePlugIn **********
Using route to config file: file:/C:/Documents%20and%20Settings/Xabi/mediavault/build/web/WEB-INF/classes/hibernate.cfg.xml
AbandonedObjectPool is used (org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool@954549)
LogAbandoned: false
RemoveAbandoned: true
RemoveAbandonedTimeout: 300
*************************************
Hibernate: select user0_.email as email0_, user0_.name as name0_, user0_.surname as surname0_, user0_.country as country0_, user0_.nickname as nickname0_, user0_.password as password0_, user0_.preferences as preferen7_0_, user0_.type as type0_ from users user0_ where user0_.email='xabier.burgos@gmail.com'
Hibernate: select userprefer0_.preference_id as preference1_3_0_, userprefer0_.toolbar_order as toolbar2_3_0_, userprefer0_.rbar_order as rbar3_3_0_, userprefer0_.show_comments as show4_3_0_, userprefer0_.show_email as show5_3_0_ from user_preferences userprefer0_ where userprefer0_.preference_id=?
Hibernate: select usertype0_.type_id as type1_1_1_, usertype0_.type_name as type2_1_1_, usertype0_.privileges as privileges1_1_, userprivil1_.privilege_id as privilege1_2_0_, userprivil1_.convert_video as convert2_2_0_, userprivil1_.convert_audio as convert3_2_0_, userprivil1_.convert_image as convert4_2_0_, userprivil1_.conserve_files as conserve5_2_0_, userprivil1_.max_fsize as max6_2_0_, userprivil1_.can_send_msg as can7_2_0_ from user_types usertype0_ left outer join user_privileges userprivil1_ on usertype0_.privileges=userprivil1_.privilege_id where usertype0_.type_id=?
Hibernate: update user_privileges set convert_video=?, convert_audio=?, convert_image=?, conserve_files=?, max_fsize=?, can_send_msg=? where privilege_id=?
This is all the information I can provide, I'm not sure if I'm doing a wrong mapping or the problem is with the transaction or... Sry I'm a complete newbie :(
[/code]