[Hibernate-JIRA] Created: (HHH-5964) IllegalArgumentException (Parameter value ... was not matching type ...) for JPA-Query: Worked with 3.3.1.GA
by Sebastian Hasait (JIRA)
IllegalArgumentException (Parameter value ... was not matching type ...) for JPA-Query: Worked with 3.3.1.GA
------------------------------------------------------------------------------------------------------------
Key: HHH-5964
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5964
Project: Hibernate Core
Issue Type: Bug
Components: entity-manager
Affects Versions: 3.6.1
Reporter: Sebastian Hasait
We have switched from core-3.3.1.GA and entity-manager-3.4.0.GA to 3.6.1.Final.
Now some queries stopped working.
This is caused by an additional type check in org.hibernate.ejb.AbstractQueryImpl#registerParameterBinding@359 which does not care about hibernate-proxies. This method is called from QueryImpl#setParameter(...). This call doesn't exist in 3.4.0.GA.
I think the proxies should be as transparent as possible. So if I get a proxy from some relation getter and put this into a query as parameter, there should be no exception.
Because the proxy cannot know the concrete type without initializing the proxy-target (reading discriminator from database) there remain four solutions:
1.) Hibernate is not checking the type for proxies OR only ensures expected type and proxy-type are related.
2.) Hibernate initializes the parameter and the type checking works without exception.
3.) Our DAO initializes the parameter before passing.
4.) We rewrite our queries to pass only the PK
I would prefer 1 or 2. :-)
Will attach test case asap.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 9 months
[Hibernate-JIRA] Created: (HHH-5858) Cannot load entities with Clob or Lob properties into stateless sessions
by James Roper (JIRA)
Cannot load entities with Clob or Lob properties into stateless sessions
------------------------------------------------------------------------
Key: HHH-5858
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5858
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.5.1
Reporter: James Roper
I have a an entity with a Clob property:
{code:java}
@Lob
private Clob clobProperty;
{code}
When I try and load it in a stateless session, I get:
{noformat}
Exception in thread "main" java.lang.ClassCastException: org.hibernate.impl.StatelessSessionImpl cannot be cast to org.hibernate.engine.jdbc.LobCreationContext
at org.hibernate.Hibernate.getLobCreator(Hibernate.java:420)
at org.hibernate.type.ClobType.nullSafeGet(ClobType.java:114)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:105)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2267)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1423)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1351)
at org.hibernate.loader.Loader.getRow(Loader.java:1251)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:619)
at org.hibernate.loader.Loader.loadSingleRow(Loader.java:307)
at org.hibernate.impl.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:254)
at org.hibernate.impl.ScrollableResultsImpl.next(ScrollableResultsImpl.java:123)
{noformat}
If Lobs in stateless sessions isn't supported, then at very least an error message to that effect should be thrown and the docs should be updated to reflect this, but I don't see why that should be the case, especially considering that both Lobs and stateless session both serve very similar purposes, they are for use when dealing with large datasets that may not fit in memory, and so could well be used together.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 9 months
[Hibernate-JIRA] Created: (HHH-4808) SessionImpl.initializeCollection() does not release JDBC connection (if outside of a transaction)
by Martin Renner (JIRA)
SessionImpl.initializeCollection() does not release JDBC connection (if outside of a transaction)
-------------------------------------------------------------------------------------------------
Key: HHH-4808
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4808
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.2, 3.2.7
Reporter: Martin Renner
Priority: Critical
With {{ConnectionReleaseMode.AFTER_TRANSACTION}} (the default), Hibernate does not release the JDBC connection when resolving a lazily loaded collection, if this happens *outside* of an active transaction.
First, I will describe, what happens if Hibernate executes a query outside of a transaction. Then I will describe how lazy collection loading behaves differently.
When the method {{list}} of a query ({{QueryImpl.java}}) is getting called, Hibernate delegates to {{SessionImpl.list()}}. After having loaded the list, {{SessionImpl.list()}} calls {{SessionImpl.afterOperation()}}, which calls {{jdbcContext.afterNontransactionalQuery()}} (as there is no active transaction). This leads to {{ConnectionManager.afterTransaction()}} which releases the JDBC connection. This is exactly what I expect to happen.
Now to the lazily loaded collection:
{{Hibernate.initialize(collection)}} and {{person.getPets().size()}} both end up in {{SessionImpl.initializeCollection()}}. This call gets dispatched down to {{Loader.doQueryAndInitializeNonLazyCollections()}} and {{Loader.doQuery()}}. The important fact is, that {{ConnectionManager.afterTransaction()}} never gets called (like in the query-example above).
The result is, that the JDBC connection is not released.
IMHO resolving of a lazily loaded collection should behave like executing a query. {{SessionImpl.initializeCollection()}} should call {{SessionImpl.afterOperation()}} in the same way as {{SessionImpl.list()}} is doing this.
I will attach a small demo application which shows the difference (concerning {{ConnectionManager}}) between queries and collections.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 9 months
[Hibernate-JIRA] Created: (HHH-6572) IdentifierGeneratorHelper.getGeneratedIdentity() assumes that id column will always be at index 1
by Richard Ballard (JIRA)
IdentifierGeneratorHelper.getGeneratedIdentity() assumes that id column will always be at index 1
-------------------------------------------------------------------------------------------------
Key: HHH-6572
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6572
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.6.3
Environment: Using Hibernate core 3.6.3 against Postgres driver 9.0-801.jdbc4 (underlying postgres version 9.0)
Reporter: Richard Ballard
If the database columns are created such that the serial id is *not* the first one, then the EntityManager.persist(Object) method sets the wrong value on the entity's @Id field (it sets it to the value of the first db column). For example:
Create the table:
CREATE TABLE info.rmbtest_course2
(
fee integer,
id bigserial NOT NULL,
starttime timestamp without time zone,
title character varying(100) NOT NULL,
CONSTRAINT rmbtest_course2_pkey PRIMARY KEY (id)
)
*Note that the id column is the second column*.
Create the entity:
package testhibernate.course;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity(name = "course")
@Table(name = "rmbTest_course2", schema = "info")
@NamedQueries(@NamedQuery(name = "Course.findByTest", query = "from course"))
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private final Long id;
@Column(name = "TITLE", length = 100, nullable = false)
private final String title;
@Column(name = "FEE")
private final int fee;
@Column(name = "startTime")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private final DateTime startTime;
public Course(final String title, final int fee, final DateTime startTime) {
this.id = null;
this.title = title;
this.fee = fee;
this.startTime = startTime;
}
/**
* Required by JPA
*/
public Course() {
id = null;
title = null;
fee = 0;
startTime = null;
}
public CourseKey getKey() {
return new CourseKey(id);
}
public String getTitle() {
return title;
}
public int getFee() {
return fee;
}
public DateTime getStartTime() {
return startTime;
}
@Override
public String toString()
{
return "Course{" +
"id=" + id +
", title='" + title + '\'' +
", fee=" + fee +
", startTime=" + startTime +
'}';
}
}
Run this code:
Course course = new Course("Core Spring", 1000, new DateTime());
course = myRepository.save(course);
System.out.println("key = " + course.getKey());
In this case the returned course.getKey() should've been the auto allocated serial id, but it is 1000, i.e. the first column in the table.
The problem is that IdentifierGeneratorHelper.get(ResultSet rs, Type type) assumes that the id column is always the first column.
As a workaround I have set my entities @Id annotations to:
...
public class Course {
@Id
@GeneratedValue(generator = "myGenerator")
@GenericGenerator(name = "myGenerator", strategy = "testhibernate.MyGenerator")
@Column(name = "ID")
private final Long id;
...
and had the following Generator code:
package testhibernate;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.PostInsertIdentityPersister;
import org.hibernate.id.ResultSetIdentifierConsumer;
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.type.CustomType;
import org.hibernate.type.Type;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MyGenerator extends IdentityGenerator
{
@Override
public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(final PostInsertIdentityPersister persister,
final Dialect dialect,
final boolean isGetGeneratedKeysEnabled) throws HibernateException
{
final InsertGeneratedIdentifierDelegate result;
if(isGetGeneratedKeysEnabled)
{
result = new MyGetGeneratedKeysDelegate(persister, dialect);
}
else
{
result = super.getInsertGeneratedIdentifierDelegate(persister, dialect, isGetGeneratedKeysEnabled);
}
return result;
}
private static class MyGetGeneratedKeysDelegate extends GetGeneratedKeysDelegate
{
private final PostInsertIdentityPersister persister;
private MyGetGeneratedKeysDelegate(final PostInsertIdentityPersister persister, final Dialect dialect)
{
super(persister, dialect);
assert persister != null;
this.persister = persister;
}
private Serializable getGeneratedIdentityByColumnName(ResultSet rs,
Type type,
String columnName) throws SQLException, HibernateException {
if ( !rs.next() ) {
throw new HibernateException( "The database returned no natively generated identity value" );
}
final Serializable id = get(rs, type, columnName);
// todo log.debug( "Natively generated identity: " + id );
return id;
}
private Serializable get(ResultSet rs, Type type, String columnName) throws SQLException, IdentifierGenerationException
{
if ( ResultSetIdentifierConsumer.class.isInstance( type ) )
{
return ( ( ResultSetIdentifierConsumer ) type ).consumeIdentifier( rs );
}
if ( CustomType.class.isInstance( type ) )
{
final CustomType customType = (CustomType) type;
if ( ResultSetIdentifierConsumer.class.isInstance( customType.getUserType() ) ) {
return ( (ResultSetIdentifierConsumer) customType.getUserType() ).consumeIdentifier( rs );
}
}
Class<?> clazz = type.getReturnedClass();
if ( clazz == Long.class )
{
return rs.getLong(columnName);
}
else if ( clazz == Integer.class )
{
return rs.getInt(columnName);
}
else if ( clazz == Short.class )
{
return rs.getShort(columnName);
}
else if ( clazz == String.class )
{
return rs.getString( columnName );
}
else if ( clazz == BigInteger.class )
{
return rs.getBigDecimal( columnName ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ).toBigInteger();
}
else if ( clazz == BigDecimal.class )
{
return rs.getBigDecimal( columnName ).setScale( 0, BigDecimal.ROUND_UNNECESSARY );
}
else
{
throw new IdentifierGenerationException("unrecognised id type : " + type.getName() + " -> " + clazz.getName());
}
}
@Override
public Serializable executeAndExtract(final PreparedStatement insert) throws SQLException
{
insert.executeUpdate();
ResultSet rs = insert.getGeneratedKeys();
try
{
final Type identifierType = persister.getIdentifierType();
Serializable result = null;
boolean useDefaultTechnique = true;
if(persister instanceof SingleTableEntityPersister)
{
final String[] idColumnNames = ((SingleTableEntityPersister)persister).getIdentifierColumnNames();
if(idColumnNames.length == 1)
{
// do it by column name
result = getGeneratedIdentityByColumnName(rs, identifierType, idColumnNames[0] );
useDefaultTechnique = false;
}
else
{
// todo - log
}
}
else
{
// todo - log
}
if(useDefaultTechnique)
{
result = IdentifierGeneratorHelper.getGeneratedIdentity(rs, identifierType);
}
return result;
}
finally
{
rs.close();
}
}
}
}
This seems to do the trick but is obviously an ugly hack.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 9 months
[Hibernate-JIRA] Created: (EJB-361) Query#setParameter(int position, Object value) wrong implementation
by Fabrice Daugan (JIRA)
Query#setParameter(int position, Object value) wrong implementation
-------------------------------------------------------------------
Key: EJB-361
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-361
Project: Hibernate Entity Manager
Issue Type: Bug
Components: EntityManager
Affects Versions: 3.3.2.GA
Reporter: Fabrice Daugan
The Hibernate JPA javax.persistence.Query#setParameter(int position, Object value) implementation does not suit to the JPA specicafication.
Indeed, the actual integer passed to the operation is converted to String by Hibernate and then used to find the named parameter.
Please have a look to the folowing stack trace :
java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IllegalArgumentException:
org.hibernate.QueryParameterException: could not locate named parameter [1]
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:185)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:240)
at org.springframework.orm.jpa.JpaTemplate$9.doInJpa(JpaTemplate.java:316)
To repoduce this error :
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 9 months