[Hibernate-JIRA] Created: (HHH-2388) Insert w/ identity column fails on Sybase but no exception occurs
by Tim Morrow (JIRA)
Insert w/ identity column fails on Sybase but no exception occurs
-----------------------------------------------------------------
Key: HHH-2388
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2388
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1
Environment: Hibernate 3.2.1.GA with annotations
Sybase jConnect 6.05 JDBC driver
Sybase ASE 15 database
Reporter: Tim Morrow
I have a scenario where storing a new entity fails (i.e. the row is not inserted) but Hibernate does not realize this. No exceptions are thrown. Later, this leads to AssertionFailures (if two such entities fail in the same session - they both have the same PK).
The problem specifically occurs with a table that has a numeric column with precision (e.g. numeric(10,4)) and an identity column when using Sybase ASE.
==========
To reproduce:
1. Use Sybase jConnect 6.05 JDBC driver with Sybase ASE 15 database.
2. Define an Entity with a long ID and BigDecimal numeric column.
3. Create a corresponding table with an identity column and numeric(10, 4) column.
For example:
hibernate.MyEntity.java:
-----------------------------------------
package hibernate;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;
@Entity
@Table(name = "z_tim_test")
public class MyEntity {
private BigDecimal cost;
private long id;
public MyEntity() {}
@Column(columnDefinition = "numeric(10,4)")
@NotNull public final BigDecimal getCost() {
return cost;
}
@GeneratedValue(strategy = GenerationType.AUTO)
@Id public final long getId() {
return id;
}
public final void setCost(BigDecimal cost) {
this.cost = cost;
}
public final void setId(long id) {
this.id = id;
}
}
Table:
-----------------------------------------
CREATE TABLE z_tim_test
(
id numeric(19) PRIMARY KEY not null,
cost numeric(10,4) not null
);
4. Write some code that stores a new entity and tries to load it:
MyEntity myEntity = new MyEntity();
myEntity.setCost(new BigDecimal("123.12345"));
session.save(myEntity);
session.flush();
session.clear();
List<MyEntity> results = session.createCriteria(MyEntity.class).list();
if (results.size() != 1) {
throw new IllegalStateException("Expected 1 result");
}
This test will throw the IllegalStateException because the row was not persisted and no errors occurred.
Reason:
* Sybase does not thrown any SQLException when you try and persist a numeric value whose scale exceeds that defined on the column. Instead, it returns an updateCount of zero and an identity column value of zero.
* Hibernate does not check the updateCount after executing the statement when using an Identity column. The offending code is in:
org.hibernate.id.IdentityGenerator$InsertSelectDelegate
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
if ( !insert.execute() ) {
while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
// do nothing until we hit the rsult set containing the generated id
}
}
ResultSet rs = insert.getResultSet();
try {
return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
}
finally {
rs.close();
}
}
It ignores the updateCount.
The net result is that the object is assigned a PK value of zero. Hibernate continues. My applicaiton is unaware that the row failed to insert.
Solution:
It would seem to me replacing the above code with:
if (!insert.execute()) {
if (insert.getUpdateCount() < 1) {
throw new HibernateException("No update occurred");
}
while (!insert.getMoreResults()) {
// do nothing until we hit the rsult set containing the generated id
}
}
Would take care of the problem?
--
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
15 years, 9 months
[Hibernate-JIRA] Created: (HHH-3002) database field name 'version' causes ClassCastException while building session factory
by Patrick Burke (JIRA)
database field name 'version' causes ClassCastException while building session factory
--------------------------------------------------------------------------------------
Key: HHH-3002
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3002
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.5
Environment: Hibernate 3.2.5, Java 1.6.0_03, MySQL 5.0.41
Reporter: Patrick Burke
Attachments: out.hib4
When a database table contains a field named 'version', like his one:
DROP TABLE IF EXISTS `tester`.`software_package`;
CREATE TABLE `tester`.`software_package` (
`software_id` int(11) NOT NULL auto_increment,
`version` varchar(100) default NULL,
`name` varchar(100) default NULL,
`root_file_id` int(11) default NULL,
PRIMARY KEY (`software_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The following error is thrown:
[java] Initial SessionFactory creation failed.java.lang.ClassCastException: org.hibernate.type.StringType cannot be cast to org.hibernate.type.VersionType
[java] Exception in thread "main" java.lang.ExceptionInInitializerError
[java] at util.HibernateUtil.<clinit>(Unknown Source)
[java] at events.EventManager.listNodes(Unknown Source)
[java] at events.EventManager.main(Unknown Source)
[java] Caused by: java.lang.ClassCastException: org.hibernate.type.StringType cannot be cast to org.hibernate.type.VersionType
[java] at org.hibernate.tuple.PropertyFactory.buildVersionProperty(PropertyFactory.java:84)
[java] at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:168)
[java] at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:434)
[java] at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:109)
[java] at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
[java] at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)
[java] at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
[java] ... 3 more
--
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
15 years, 10 months
[Hibernate-JIRA] Created: (HHH-3045) Duplicated column aliases in scalar query
by Anderson Souza (JIRA)
Duplicated column aliases in scalar query
-----------------------------------------
Key: HHH-3045
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3045
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.5
Environment: Hibernate 3.2.4SP1, 3.2.5GA
Oracle 10g
Reporter: Anderson Souza
Priority: Critical
Attachments: ddl-tables.sql, dominio.zip
The HQL bellow works fine, but when I add a call to a funcion in the select clause the SQL generated has duplicated aliases and it generate error on query execution, because the query is paginated.
{code}
select a
from Area a
inner join fetch a.horarioPadrao
left outer join fetch a.horarioTemporario as hrtemp
{code}
The SQL generated for this query is:
{code}
select * from (
select area0_.cod_local as cod1_15_0_,
horarioare1_.cod_area as cod1_6_1_,
horarioare2_.cod_area as cod1_7_2_,
area0_.des_local as des2_15_0_,
area0_.sig_local as sig3_15_0_,
area0_.flg_extinto as flg4_15_0_,
horarioare1_.hr_hora_ini as hr2_6_1_,
horarioare1_.hr_hora_fim as hr3_6_1_,
horarioare1_.flg_fim_semana as flg4_6_1_,
horarioare2_.hr_hora_ini as hr2_7_2_,
horarioare2_.hr_hora_fim as hr3_7_2_,
horarioare2_.flg_fim_semana as flg4_7_2_,
horarioare2_.dat_ini_vigencia as dat5_7_2_,
horarioare2_.dat_fim_vigencia as dat6_7_2_
from esq_fp.tb_local area0_
inner join tb_horario_local_padrao horarioare1_ on area0_.cod_local=horarioare1_.cod_area
left outer join tb_horario_local_temporario horarioare2_ on area0_.cod_local=horarioare2_.cod_area
where 1=1
order by area0_.sig_local )
where rownum <= ?
{code}
The scalar HQL query that generate duplicated column names is:
{code}
select a, count(*)
from Area a
inner join fetch a.horarioPadrao
left outer join fetch a.horarioTemporario as hrtemp
{code}
The SQL generated is:
{code}
select * from (
select area0_.cod_local as col_0_0_,
count(*) as col_1_0_,
horarioare1_.cod_area as cod1_6_1_,
horarioare2_.cod_area as cod1_7_2_,
area0_.cod_local as cod1_15_0_,
horarioare1_.cod_area as cod1_6_1_,
horarioare2_.cod_area as cod1_7_2_,
area0_.des_local as des2_15_0_,
area0_.sig_local as sig3_15_0_,
area0_.flg_extinto as flg4_15_0_,
horarioare1_.hr_hora_ini as hr2_6_1_,
horarioare1_.hr_hora_fim as hr3_6_1_,
horarioare1_.flg_fim_semana as flg4_6_1_,
horarioare2_.hr_hora_ini as hr2_7_2_,
horarioare2_.hr_hora_fim as hr3_7_2_,
horarioare2_.flg_fim_semana as flg4_7_2_,
horarioare2_.dat_ini_vigencia as dat5_7_2_,
horarioare2_.dat_fim_vigencia as dat6_7_2_
from esq_fp.tb_local area0_
inner join tb_horario_local_padrao horarioare1_ on area0_.cod_local=horarioare1_.cod_area
left outer join tb_horario_local_temporario horarioare2_ on area0_.cod_local=horarioare2_.cod_area
where 1=1
order by area0_.sig_local )
where rownum <= ?
{code}
As you can see the aliases cod1_6_1_ and cod1_7_2_ are repeated and this repetition breaks the paginated query, beacause the main query appears in the from clause.
The HBM's and classes are attached.
--
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
15 years, 10 months
[Hibernate-JIRA] Created: (HHH-3058) When using native sql query and multiple selects with setMaxResults, Hibernate inserts the TOP statement in the first query
by Sean Blaes (JIRA)
When using native sql query and multiple selects with setMaxResults, Hibernate inserts the TOP statement in the first query
---------------------------------------------------------------------------------------------------------------------------
Key: HHH-3058
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3058
Project: Hibernate3
Issue Type: Bug
Components: query-sql
Affects Versions: 3.2.4.sp1
Environment: Hibernate 3.2.4sp1, Microsoft SQL Server
Reporter: Sean Blaes
Priority: Minor
When using a query similar to the following:
DECLARE @SUB_TABLE TABLE(
ID INT
)
INSERT INTO @SUB_TABLE
SELECT ID
FROM FOO
SELECT *
FROM BAR
INNER JOIN @SUB_TABLE
ON ...
Then if I call setMaxResults(100) on the query object. It inserts "TOP 100" in the first query, which isn't really what would be expected. Since the second SELECT actually consists of the data that will be returned, the TOP 100 statement should go there.
I'd expect it's an easy fix. Just start your search for SELECT from the bottom rather than the top. However, I guess you have to make sure you're not hitting a subquery of a larger select either... I may try cooking up a patch this weekend for this if I can find the time, and I'll attach it to this issue if I do.
--
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
15 years, 10 months
[Hibernate-JIRA] Created: (HHH-1989) Deleted object remains referenced in 2nd level cache collections
by Justin Haddad (JIRA)
Deleted object remains referenced in 2nd level cache collections
----------------------------------------------------------------
Key: HHH-1989
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1989
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.0.cr2
Environment: Spring 1.2.8, Hibernate 3.2, Postgres 8.0.3
Reporter: Justin Haddad
This problem seems identical to issue NH-678. I have enabled caching for an one-to-many association. I use Ehcache. I have a test in which I load the parent object along with its collection. Both the parent and the collection wind up in the 2nd level cache. I then delete an object that is in the collection, not by removing it from the collection, but rather by doing a delete on the object itself. After deleting, I try to reload the parent and get the following exception (User#3102 is the deleted object):
aused by: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.bluenotenetworks.common.management.sm.User#3102]
at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:372)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:128)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:178)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:839)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
at org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:177)
at org.hibernate.collection.PersistentSet.initializeFromCache(PersistentSet.java:101)
at org.hibernate.cache.entry.CollectionCacheEntry.assemble(CollectionCacheEntry.java:35)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.initializeCollectionFromCache(DefaultInitializeCollectionEventListener.java:130)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:48)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1705)
(continues on)
I stepped through the code in the debugger and can see that the object's ID (3102 in this case) remains in the cached collection even after the deletion.
--
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
15 years, 10 months
[Hibernate-JIRA] Created: (HHH-3075) Should be possible to register UserTypes for known property types (classes) in configuration
by Martin Probst (JIRA)
Should be possible to register UserTypes for known property types (classes) in configuration
--------------------------------------------------------------------------------------------
Key: HHH-3075
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3075
Project: Hibernate3
Issue Type: Improvement
Components: core
Environment: n/a
Reporter: Martin Probst
Priority: Minor
Currently, when persisting primitive properties of a class that are not known to Hibernate, there are only cumbersome ways to tell Hibernate that a certain UserType should be used. Good example is Joda Time:
<pre>
@Entity
class MyClass {
org.joda.time.DateTime foo;
}
</pre>
.. which will result in ugly binary fields in database. Next try:
<pre>
@Entity
class MyClass {
@Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
org.joda.time.DateTime foo;
}
</pre>
That works, but now I have to specify that on all time fields of all classes. Plus it's different types for different classes, which makes it more messy. And it's simply a string in code, so it's fragile to refactoring, code move, etc. TypeDefs allow a shorter handle for certain types, but don't really address the refactoring issues.
A better way might be to allow configurations to register UserTypes for known classes. E.g. have a configuration directive like this:
<mappable-type class="org.joda.time.DateTime" usertype="org.joda.time.hibernate.DateTimeType"/>
This would allow the classes to stay clean from type mappings and reduce coupling between domain objects and persistence mapping.
This might be as easy as allowing the org.hibernate.type.TypeFactory map to be extended at configuration time.
--
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
15 years, 10 months
[Hibernate-JIRA] Created: (HHH-2645) Synchronization bottleneck in EntityModeToTuplizerMapping
by Erik Bergersjö (JIRA)
Synchronization bottleneck in EntityModeToTuplizerMapping
---------------------------------------------------------
Key: HHH-2645
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2645
Project: Hibernate3
Issue Type: Patch
Components: core
Affects Versions: 3.2.4.sp1, 3.2.4, 3.2.3
Environment: Hibernate 3.2.3 (and later), Sun's JDK 1.4.2_12 (server VM) on SunOS 5.10, Oracle 10g R2
Reporter: Erik Bergersjö
Priority: Minor
We have had a major performance bottleneck in EntityModeToTuplizerMapping with Hibernate version 3.2.3 and the code for that class in 3.2.4sp1 is unchanged. We have found a solution that solves the issue and would like to get it into the real version. I submitted to the user forum first and was asked to create a JIRA issue.
The problematic line is:
private final Map tuplizers = Collections.synchronizedMap( new SequencedHashMap() );
We have changed it to (using util.concurrent):
private final Map tuplizers = new EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap();
This change alone makes our use cases six times faster. The difference is that ConcurrentReaderHashMap handles concurrent readers much better, they don't have to wait for each other.
The problem occurs when a high number of threads try to initialize sets (see mapping below). A thread dump showed a high number of threads waiting for the same monitor, see partial stack trace below.
The code runs on Sun's JDK 1.4.2_12 (server VM) on SunOS 5.10 and the kernel spends a lot of time handling mutexes with the original implementation. That time disappears from the radar screen with the fixed version.
Example mapping for set:
[code]
<set name="lines" lazy="true" inverse="true" cascade="all-delete-orphan">
<key>
<column name="col1" not-null="true" />
<column name="col2" not-null="true" />
</key>
<one-to-many class="LineClass" />
</set>
[/code]
Stack trace (partial):
"Thread-108" prio=5 tid=0x05852e90 nid=0x103 waiting for monitor entry [0x3ed7e000..0x3ed7fc28]
at java.util.Collections$SynchronizedMap.get(Collections.java:1942)
- waiting to lock <0x89d30788> (a java.util.Collections$SynchronizedMap)
at org.hibernate.tuple.EntityModeToTuplizerMapping.getTuplizerOrNull(EntityModeToTuplizerMapping.java:53)
at org.hibernate.tuple.EntityModeToTuplizerMapping.getTuplizer(EntityModeToTuplizerMapping.java:66)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
at org.hibernate.type.ComponentType.isEqual(ComponentType.java:141)
at org.hibernate.engine.CollectionKey.equals(CollectionKey.java:50)
at java.util.HashMap.eq(HashMap.java:274)
at java.util.HashMap.get(HashMap.java:323)
at org.hibernate.engine.loading.CollectionLoadContext.getLocalLoadingCollectionEntry(CollectionLoadContext.java:163)
at org.hibernate.engine.loading.CollectionLoadContext.locateLoadingCollectionEntry(CollectionLoadContext.java:150)
at org.hibernate.engine.loading.CollectionLoadContext.getLoadingCollection(CollectionLoadContext.java:92)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1003)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:646)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:591)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
--
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
15 years, 10 months