[Hibernate-JIRA] Created: (HHH-3657) Custom types with auto-generated keys
by David Nadaski (JIRA)
Custom types with auto-generated keys
-------------------------------------
Key: HHH-3657
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3657
Project: Hibernate Core
Issue Type: New Feature
Components: core
Affects Versions: 3.3.1
Reporter: David Nadaski
Attachments: IdentifierGeneratorFactory.java
Hibernate should provide for custom types to be usable with auto-generated ids.
Attached is a patch, untested but supposedly working (it works for our site flawlessly), and here's a short description, copied from 2 email that I've sent to the dev list and forum:
So in response to my previous mail, I've applied a short fix for IdentifierGeneratorFactory to enable custom types to be used for auto-generated keys.
Here's IdentifierGeneratorFactory's modified public static Serializable get(....) method, which was extended based on the 3.3.1.GA release:
public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
Class clazz = type.getReturnedClass();
if ( clazz == Long.class ) {
return new Long( rs.getLong( 1 ) );
}
else if ( clazz == Integer.class ) {
return new Integer( rs.getInt( 1 ) );
}
else if ( clazz == Short.class ) {
return new Short( rs.getShort( 1 ) );
}
else if ( clazz == String.class ) {
return rs.getString( 1 );
}
else {
// try to instantiate the custom type through reflection
try {
Constructor<?>[] constructors = type.getReturnedClass().getConstructors();
for (Constructor<?> constructor : constructors)
{
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 1)
if (Long.class.equals(parameterTypes[0]))
return (Serializable) constructor.newInstance(rs.getLong(1));
else if (Integer.class.equals(parameterTypes[0]))
return (Serializable) constructor.newInstance(rs.getInt(1));
else if (Short.class.equals(parameterTypes[0]))
return (Serializable) constructor.newInstance(rs.getShort(1));
else if (String.class.equals(parameterTypes[0]))
return (Serializable) constructor.newInstance(rs.getString(1));
}
} catch (Throwable t) {
throw new IdentifierGenerationException( "Error instantiating custom type: " + type + " with value class: " + type.getReturnedClass(), t );
}
throw new IdentifierGenerationException( "Supplied custom type doesn't have a 1-argument constructor which could take either long, integer, short or string: " + type.getReturnedClass().getName() );
}
}
So this would allow you to use any class for an auto-generated ID, for example:
public class UniqueInteger implements Serializable {
private Integer internal;
public UniqueInteger()
{
}
public UniqueInteger(Integer internal)
{
this.internal = internal;
}
}
The only requirement is that it should have a 1-argument constructor that can take either long, integer, short or string.
Which I think makes sense.
Please submit your feedback and thoughts on this!
--Dávid
--------------------------------------------------------------------------------
From: Nádaski Dávid [mailto:david@aquilanet.hu]
Sent: Wednesday, December 10, 2008 7:23 AM
To: 'hibernate-dev(a)lists.jboss.org'
Subject: Using custom types for auto-generated id columns
Hi,
I was trying to use a custom type for which there was a valid Type implementation, and have run into the following error:
28240 [http-8080-1] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.id.IdentifierGenerationException: this id generator generates long, integer, short or string
at org.hibernate.id.IdentifierGeneratorFactory.get(IdentifierGeneratorFactory.java:116)
etc.
I'm using MySQL.
Looking at the source, it seems like Hibernate doesn't support anything other than a "long, integer, short or string".
In the parameters of IdentifierGeneratorFactory.get(....), there's one called "Type type". This gets mapped correctly to my custom, but since that's none of those "primitive" types, I get the error - but since the Type information is available, it could easily be used to map say a String using Type.nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner), since we have both the ResultSet and the Type parameter available in IdentifierGeneratorFactory.get(ResultSet rs, Type type). So then, the proper custom type could be returned if it indeed supports this kind of mapping (which is by definition it's job).
So I propose a patch should be made to IdentifierGeneratorFactory that would enable the use of custom types for identity-generated columns.
It's possible that I'm missing something, in that case please point out my error.
Upon request, I think I can supply the appropriate patch, although it seems easy to code.
Thanks,
David
That's the emails, you'll find the patch 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
16 years
[Hibernate-JIRA] Created: (HHH-3654) A bug on set with composite element deletes the elements first instead of updating
by leela (JIRA)
A bug on set with composite element deletes the elements first instead of updating
----------------------------------------------------------------------------------
Key: HHH-3654
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3654
Project: Hibernate Core
Issue Type: Bug
Reporter: leela
<set name="pictureCollection"
lazy="true"
access="field"
cascade="save-update"
outer-join="false"
table="tablec">
<key column="aid" />
<composite-element class="tablec">
<many-to-one name="b" column="bid" lazy="proxy" access="field" not-null="true" />
<property name="x" type="int" access="field"/>
<property name="seqno" type="int" access="field"/>
</composite-element>
</set>
I am trying to delete the first entry and then update the seqno accordingly for the remaining entries.
when the commit is done, hibernate performs delete operation followed by insert for the remaining entries in the collection, instead of updating the dirty objects.
delete from tablec where aid=? and bid=?
insert into tablec (aid, bid, x, seqno) values (?, ?, ?, ?)
Is not this a bug? If we have 1000 objects in the collection, would not this cause a big performace impact?
Please help me on this.
--
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
16 years
[Hibernate-JIRA] Created: (HHH-3653) Allow lazy loading for one-to-one association when constrained="false"
by Eric Sirianni (JIRA)
Allow lazy loading for one-to-one association when constrained="false"
----------------------------------------------------------------------
Key: HHH-3653
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3653
Project: Hibernate Core
Issue Type: Improvement
Components: core
Affects Versions: 3.3.1
Reporter: Eric Sirianni
Hibernate currently has a documented restriction on one-to-one associations that prohibits lazy loading when constrained="false"
lazy (optional - defaults to proxy): By default, single point associations are proxied. lazy="no-proxy" specifies that the property should be fetched lazily when the instance variable is first accessed (requires build-time bytecode instrumentation). lazy="false" specifies that the association will always be eagerly fetched. Note that if constrained="false", proxying is impossible and Hibernate will eager fetch the association!
The rationale for this seems to be that
- If constrained="false", then hibernate has to execute a SELECT on the associated table in order to set the parent's reference to NULL vs. a child proxy
- Since hibernate has to do this SELECT anyway, then why not just load the actual child record instead of the proxy
This is summarized in http://www.hibernate.org/162.html:
"But a SELECT to check presence is just inefficient because the same SELECT may not just check presence, but load entire object. So lazy loading goes away."
The notes on that page do a good job explaining the flaw in this rationale:
---
This is hugely wrong. Imagine a table with a FK and a 20M blob of data
in each row. Lazy loading the blob when displaying a list of rows for
example is useful, even if you have to select the PK column to find out
the rows exist. Lazy loading has more uses than avoiding the SQL
execution. In this case avoiding the memory overhead of creating
perhaps hundreds of M of data in memory when it's not needed.
---
I have a one-to-one where the foreign table is very large and
holds a bunch of infrequently used information. Most parent records do
not need a detail record as they do not have any of the information it
stores. Parent records are cached and heavily used. It would be a waste
to fill up memory or table space with mostly unused detail records.
---
My project is in the exact same situation. We have one-to-one records where the child objects have a significant amount of details (CLOBs) that take up a lot of space in memory. We would like these to be lazy loaded.
Please consider this feature request. I don't think the implementation would be very difficult. It would be straight forward to add a join on the id column of the
foreign table. That would permit Hibernate to discover whether an optional one-to-one object was present and have enough info to create the proxy vs. the NULL reference.
--
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
16 years
[Hibernate-JIRA] Created: (HHH-3651) HQL delete with subquery generates invalid (ambiguous) SQL
by Robin Houston (JIRA)
HQL delete with subquery generates invalid (ambiguous) SQL
----------------------------------------------------------
Key: HHH-3651
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3651
Project: Hibernate Core
Issue Type: Bug
Components: query-hql
Affects Versions: 3.3.1
Environment: Hibernate 3.3.1GA, PostgreSQL database
Reporter: Robin Houston
Attachments: Edge.java, Node.java, schema.sql
A simple test case demonstrating this bug is attached. The HQL query
delete Node n where n in (
select grandchild
from Edge grandparent_child
, Edge child_grandchild
left join child_grandchild.target as grandchild
where grandparent_child.target = child_grandchild.source
and grandparent_child.source.name = :nodeName
)
generates the following SQL (formatted for readability):
delete from node where id in (
select id
from edge edge1_
, edge edge2_
left outer join node node3_ on edge2_.target_id = node3_.id
, node node4_
where edge1_.source_id=node4_.id
and edge1_.target_id = edge2_.source_id
and node4_.name = ?
)
Note that the 'select id' is ambiguous; it could refer either to node3_.id or node4_.id. (It should be node3_, of course.) This ambiguity causes the PostgreSQL parser to throw an exception.
I realise that the problem could be avoided in this particular example by removing the join and directly selecting child_grandchild.target. However, this is just a simple test case derived from a much more complicated example where such a workaround doesn't seem to be possible. (We are currently circumventing the problem by using an SQL delete statement.)
I attach the mapped classes and the schema definition for this test case.
Robin
--
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
16 years
[Hibernate-JIRA] Created: (EJB-406) Unclosed sessions/transaction
by Juraci Paixao Krohling (JIRA)
Unclosed sessions/transaction
-----------------------------
Key: EJB-406
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-406
Project: Hibernate Entity Manager
Issue Type: Bug
Components: EntityManager
Environment: Tested in DB2 v8, probably affects most RDBMS's as well
Reporter: Juraci Paixao Krohling
Assignee: Juraci Paixao Krohling
Attachments: TestCase.java.diff
Some tests opens transactions and do not properly close them, causing some RDBMS's to hang indefinitely, waiting for the transaction to be closed before dropping the entities used in the test.
To encourage the closing of these open transaction, the following patch makes the test to fail if the transaction is not finished. Also, the test rolls back the transaction, to release the transaction in the database, enabling it to drop all entities used by the test.
Also, a warning was also added to the parent test case for the project, informing when a test case is not closing the EM.
--
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
16 years
[Hibernate-JIRA] Commented: (HHH-912) Use of DetachedCriteria
by Steve Van Reeth (JIRA)
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-912?page=co... ]
Steve Van Reeth commented on HHH-912:
-------------------------------------
I have the same problem: for performance purpose, I have to do this:
SELECT this_.ID AS id33_0_, this_.in_record_id AS in2_33_0_,
this_.created_ts AS created3_33_0_, this_.ext_app_id AS ext4_33_0_,
this_.file_id AS file8_33_0_, this_.line_number AS line5_33_0_,
this_.linked_ts AS linked6_33_0_, this_.status_id AS status7_33_0_
FROM myschema.ext_in_record this_
WHERE this_.ID IN (SELECT ID
FROM (SELECT ID
FROM myschema.ext_in_record
WHERE status_id = 0
ORDER BY ID)
WHERE ROWNUM < = 500);
It's impossible to do with Criteria in Hibernate 3.2.6.
> Use of DetachedCriteria
> -----------------------
>
> Key: HHH-912
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-912
> Project: Hibernate Core
> Issue Type: Improvement
> Components: core
> Affects Versions: 3.0.5
> Environment: All
> Reporter: Frank Verbruggen
> Priority: Minor
>
> The class org.hibernate.criterion.DetachedCriteria should represent a criteria object on which all the operations available to a Criteria object that do NOT require a Session object are available.
> Two such operations are setFirstResult() and setMaxResults().
> These are unfortunately enough not available.
> There probably are more methods missing that need to be added but these two in particular are important to me.
> See http://opensource2.atlassian.com/projects/spring/browse/SPR-1254.
> Can they be added in the next release ?
> Kind regards
> Frank Verbruggen
--
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
16 years