Re: [hibernate-dev] HHH-6726 LONG and LONG RAW column types in Oracle
by Łukasz Antoniak
Currently Oracle supports database versions from 10.1 to 11.2 [1]. LONG
and LONG RAW data types are deprecated since version 8 and 8i (released
before September 2000) [2]. Oracle keeps those column types only for
backward compatibility [3].
I tried the following scenario (Oracle 10gR2):
1. Create schema with "hibernate.hbm2ddl.auto" set to "create". The LONG
column is created.
2. Insert some data.
3. Modify Oracle dialect as Gail suggested. Avoid setting
"hibernate.hbm2ddl.auto".
4. Insert some data.
To my surprise the test actually passed :). However, I think that we
cannot guaranty the proper behavior in every situation.
As for performance, ImageType is extracted by calling
ResultSet.getBytes() method, which fetches all data in one call [4]. I
don't suppose a major performance difference when data is streamed in
another call. oracle.jdbc.driver.LongRawAccessor.getBytes also fetches
data by reading the stream.
The bug reading LONG column affects JDBC drivers since version 10.2.0.4.
I think that we have to choose between:
- changing Oracle10gDialect. Make a not about it in migration guide to
4.0 and update "5.2.2. Basic value types" chapter in Hibernate
documentation.
- introducing Oracle11gDialect. It can sound weird to access Oracle 10g
database with Oracle 11g dialect.
- disabling execution of Hibernate tests that fail because of this issue
with @SkipForDialect (and maybe develop another version of them with
CLOBs and BLOBs, @RequiresDialect). Hibernate is written correctly
according to "Default Mappings Between SQL Types and Java Types"
(referenced earlier by Gail) and this is more Oracle's JDBC
implementation issue. This option came to my mind, but it's weird :P.
I would vote for the first option.
Regards,
Lukasz Antoniak
[1]
http://www.oracle.com/us/support/library/lifetime-support-technology-0691...
(page 4)
[2]
http://download.oracle.com/docs/cd/A91202_01/901_doc/server.901/a90120/ch...
[3]
http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/datatype.htm
[4] "Getting a LONG RAW Data Column with getBytes"
http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/jstreams.htm
Strong Liu pisze:
> I think oracle 11g is the only one supported DB version by oracle, can we just introduce a new oracle dialect with suggested changes, and deprecate all other existed oracle dialects? this won't affects users app
>
> -----------
> Strong Liu <stliu(a)hibernate.org>
> http://hibernate.org
> http://github.com/stliu
>
> On Oct 15, 2011, at 11:14 AM, Scott Marlow wrote:
>
>> How does this impact existing applications? Would they have to convert
>> LONGs to CLOBs (and LONGRAWs to BLOBs) to keep the application working?
>>
>> As far as the advantage of CLOB over TEXT, if you read every character,
>> which one is really faster? I would expect TEXT to be a little faster,
>> since the server side will send the characters before they are asked
>> for. By faster, I mean from the application performance point of view. :)
>>
>> Could this be changed in a custom Oracle dialect? So new
>> applications/databases could perhaps use that and existing applications
>> might use LONGs a bit longer via the existing Oracle dialect.
>>
>> On 10/14/2011 09:22 PM, Gail Badner wrote:
>>> In [1], I am seeing the following type mappings:
>>>
>>> Column type: LONG -> java.sql.Types.LONGVARCHAR -> java.lang.String
>>> Column type: LONGRAW -> java.sql.Types.LONGVARBINARY -> byte[]
>>>
>>> org.hibernate.type.TextType is consistent with the mapping for LONG.
>>>
>>> org.hibernate.type.ImageType is consistent with the mapping for LONGRAW.
>>>
>>> From this standpoint, the current settings are appropriate.
>>>
>>> I understand there are restrictions when LONG and LONGRAW are used and I see from your other message that there is Oracle documentation for migrating to CLOB and BLOB.
>>>
>>> I agree that changing column type registration as follows (for Oracle only) should fix this:
>>> registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
>>> registerColumnType( Types.VARBINARY, "blob" );
>>>
>>> registerColumnType( Types.LONGVARCHAR, "clob" );
>>> registerColumnType( Types.LONGVARBINARY, "blob" );
>>>
>>> registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
>>> registerColumnType( Types.VARCHAR, "clob" );
>>>
>>> Steve, what do you think? Is it too late to make this change for 4.0.0?
>>>
>>> [1] Table 11-1 of Oracle® Database JDBC Developer's Guide and Reference, 11g Release 1 (11.1) (http://download.oracle.com/docs/cd/B28359_01/java.111/b31224/datacc.htm#g...)
>>> [2] Hibernate Core Migration Guide for 3.5 (http://community.jboss.org/wiki/HibernateCoreMigrationGuide35)
>>> [3] Table 2-10 of Oracle® Database SQL Language Reference
>>> 11g Release 1 (11.1) (http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/sql_elemen...)
>>>
>>> ----- Original Message -----
>>>> From: "Łukasz Antoniak"<lukasz.antoniak(a)gmail.com>
>>>> To: hibernate-dev(a)lists.jboss.org
>>>> Sent: Thursday, October 13, 2011 12:50:13 PM
>>>> Subject: [hibernate-dev] HHH-6726 LONG and LONG RAW column types in Oracle
>>>>
>>>> Welcome Community!
>>>>
>>>> I have just subscribed to the list and wanted to discuss HHH-6726
>>>> JIRA
>>>> issue.
>>>>
>>>> Gail Badner wrote
>>>> (http://lists.jboss.org/pipermail/hibernate-dev/2011-October/007208.html):
>>>> HHH-6726 (Oracle : map TextType to clob and ImageType to blob)
>>>> https://hibernate.onjira.com/browse/HHH-6726
>>>> There have been a number of issues opened since the change was made
>>>> to
>>>> map TextType (LONGVARCHAR) 'long' and ImageType (LONGVARBINARY) to
>>>> 'long
>>>> raw'. This change was already documented in the migration notes.
>>>> Should
>>>> the mapping for Oracle (only) be changed back to clob and blob?
>>>>
>>>> HHH-6726 is caused by an issue in Oracle JDBC driver (version
>>>> 10.2.0.4
>>>> and later). This bug appears when LONG or LONG RAW columns are
>>>> accessed
>>>> not as first or last while processing SQL statement.
>>>>
>>>> I have discussed the topic of mapping TextType to CLOB and ImageType
>>>> to
>>>> BLOB (only in Oracle dialect) with Strong Liu. Reasons for doing so:
>>>> - Oracle allows only one LONG / LONG RAW column per table. This might
>>>> be
>>>> the most important from Hibernate's perspective.
>>>> - LONG / LONG RAW - up to 2 GB, BLOB / CLOB - up to 4 GB.
>>>> - In PL/SQL using LOBs is more efficient (random access to data).
>>>> LONG
>>>> only sequential.
>>>> - LONG and LONG RAW are deprecated.
>>>>
>>>> What is your opinion?
>>>>
>>>> Regards,
>>>> Lukasz Antoniak
>>>> _______________________________________________
>>>> hibernate-dev mailing list
>>>> hibernate-dev(a)lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>>
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev(a)lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev(a)lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
8 years, 11 months
Proxies and typing
by Steve Ebersole
In regards to the new "load access", a user asked why we don't leverage
generics.
The problem is the existence of @Proxy#proxyClass. We have the same
issue with Session#load/get taking the entity Class. We can't use a
generic sig like:
public <T> T load(Class<T> entityType, ...)
because at times we return objects that are not typed to <T>. I have to
dive back into the specifics, but IIRC the problem is that we don't do
the expected thing and have the generated proxy class extend from the
entity class if @Proxy#proxyClass names an interface. I remember this
change way back when, but the specifics of why escape me at the moment.
IMO I think providing generic signatures would obviously be a great
improvement. Is it enough to change this behavior?
WDYT?
--
steve(a)hibernate.org
http://hibernate.org
12 years, 9 months
Queries executed with bidirectional @OneToOnes
by Guillaume Smet
Hi,
It's not something new as we checked that it was already the case with
Hibernate 3.6 but we just hit an annoying problem with @OneToOne
annotation if the relation is bidirectional.
Simplified example:
class A {
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
private B b;
}
class B {
@OneToOne(mappedBy = "b")
private A a;
}
If we insert 1 object in each table and we try to list the objects of
A, the following queries are executed:
1. select a0_.id as id55_, a0_.b_id as b2_55_ from A a0_
2. select b0_.id as id54_1_, a1_.id as id55_0_, a1_.b_id as b2_55_0_
from B b0_ left outer join A a1_ on b0_.id=a1_.b_id where b0_.id=1
3. select a0_.id as id55_1_, a0_.b_id as b2_55_1_, b1_.id as id54_0_
from A a0_ left outer join B b1_ on a0_.b_id=b1_.id where a0_.b_id=1
I don't understand the need for the third query. And this query
quickly becomes a problem as it's executed for each EAGER @OneToOne
relationship of A.
In our application, we have a lot of @OneToOne relationships on an
entity and a variant of the third query (which is big as the entity is
big and the third query tries to populate all the EAGER relations) is
executed for each @OneToOne of the base entity.
I can provide more information if needed. I don't know if it's a
limitation or a bug, that's why I haven't created a JIRA issue yet but
I find this behaviour really suboptimal.
As a temporary workaround, we made the @OneToOne relations
unidirectional which makes our application usable again.
Any pointers on where the problem could be or a confirmation that it's
something expected?
Thanks.
--
Guillaume
12 years, 9 months
natural-id to primary key cache
by Steve Ebersole
Historically natural-id look ups were accomplished by leveraging
Criteria queries. Caching was handled through the second level query
cache.
One of the new things in 4.1 is the dedicated natural-id loading API.
So the caching will be quite different here. I am a little leery about
making a breaking changes in 4.1 after all the changes in 4.0 if we can
avoid it. If we can't we can't. One thought for this was to use a
SessionFactory scoped "cache" for this in 4.1 and then add a new second
level cache Region construct for this in 5.0. The *only* benefit is to
keep the second level cache SPI the same between 4.0 and 4.1. Is that
worth it? Any thoughts?
--
steve(a)hibernate.org
http://hibernate.org
12 years, 9 months
Natural ids and inheritance
by Steve Ebersole
Another discrepancy between hbm.xml and annotations currently is the
definition of natural ids. hbm.xml only allows natural ids to be
defined on the root entity, annotations allow it to be defined on any
level of the hierarchy, even across classes.
We need to decide what we want to support. 2 things to consider here are:
1) whether we limit @NaturalId to only root entity meta (and maybe
@MappedSuperclass for root entities)
2) if we do not limit, what @NaturalId spread across a hierarchy "means"
In the second point, consider:
class A
@NaturalId
key1
class AA extends A
@NaturalId
key2
Personally I vote for limiting @NaturalId to the root entity. This
allows caching to work just like it does for identifiers.
--
steve(a)hibernate.org
http://hibernate.org
12 years, 10 months
Beginner's tasks for Hibernate Search and Hibernate OGM
by Emmanuel Bernard
I will be doing a Hackergarten session next week with Hibernate Search and OGM as projects. A hackergarten is one project master and a few wannabe contributors hacking for a night on a few issues. I am looking for beginner materials for Hibernate OGM or Search. If you have ideas, let me know.
Emmanuel
12 years, 10 months
infinispan test fails occasionally on hudson
by Strong Liu
could someone take a look?
org.hibernate.test.cache.infinispan.functional.ConcurrentWriteTest.testManyUsers
Error Message
java.util.concurrent.TimeoutException
Stacktrace
java.util.concurrent.TimeoutException
at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:222)
at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:399)
at org.hibernate.test.cache.infinispan.functional.ConcurrentWriteTest.testManyUsers(ConcurrentWriteTest.java:223)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:63)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.hibernate.testing.junit4.FailureExpectedHandler.evaluate(FailureExpectedHandler.java:59)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.hibernate.testing.junit4.BeforeClassCallbackHandler.evaluate(BeforeClassCallbackHandler.java:43)
at org.hibernate.testing.junit4.AfterClassCallbackHandler.evaluate(AfterClassCallbackHandler.java:42)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:51)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:63)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:75)
at $Proxy3.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.TypeCastDispatch.dispatch(TypeCastDispatch.java:30)
at org.gradle.messaging.remote.internal.WorkerProtocol.handleIncoming(WorkerProtocol.java:53)
at org.gradle.messaging.remote.internal.WorkerProtocol.handleIncoming(WorkerProtocol.java:31)
at org.gradle.messaging.remote.internal.ProtocolStack$ProtocolStage.handleIncoming(ProtocolStack.java:167)
at org.gradle.messaging.remote.internal.ProtocolStack$BottomStage.handleIncoming(ProtocolStack.java:277)
at org.gradle.messaging.remote.internal.ProtocolStack$BottomConnection$1.run(ProtocolStack.java:299)
at org.gradle.messaging.remote.internal.ProtocolStack$ExecuteRunnable.dispatch(ProtocolStack.java:120)
at org.gradle.messaging.remote.internal.ProtocolStack$ExecuteRunnable.dispatch(ProtocolStack.java:116)
at org.gradle.messaging.dispatch.AsyncDispatch.dispatchMessages(AsyncDispatch.java:132)
at org.gradle.messaging.dispatch.AsyncDispatch.access$000(AsyncDispatch.java:33)
at org.gradle.messaging.dispatch.AsyncDispatch$1.run(AsyncDispatch.java:72)
at org.gradle.messaging.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
-------------------------
Best Regards,
Strong Liu <stliu at hibernate.org>
http://about.me/stliu/bio
12 years, 10 months
4.1.1
by Steve Ebersole
Just a reminder that 4.1.1 is slated for next week. If there is any
work you want to get in to 4.1.1 please keep that in mind, or if you
have issues assigned to you scheduled for 4.1.1.
--
steve(a)hibernate.org
http://hibernate.org
12 years, 10 months
Annotations to separate package?
by Sven Rienstra
Hi all,
We've just migrated some of our products from Hibernate 3 to Hibernate 4. We ran into some problems because Envers is now automatically starting when it is on the classpath. I think this is a really nice feature, however in our case most of our products need Envers on the classpath even though only some product are actually using Envers. This is because we have made a common data model which is used by most of our products, some of these model classes have @Audited annotations, so Envers is required on the classpath.
We now explicitly turned of Envers in products where it is not needed, but it would be nice if there was a separate jar containing only the annotations. Not exclusively for Envers, but a jar containing all Hibernate annotations.
Do you guys think this is a good idea?
Sven
12 years, 10 months
Voldemort maven module for Hibernate OGM
by skawashima@uchicago.edu
Hi,
I wrote sample implementations for Voldemort,Redis and Riak on Hibernate OGM a couple of weeks ago. Based on them, I created a Voldemort maven module and put it on my github repository at https://github.com/seiyak/hibernate-ogm. The project was forked from the original one and the modifications were applied on it following Emmanuel's advice on the previous mailing list. I put README.md in hibernate-ogm-voldemort directory, so please read it before typing 'mvn clean install'. Voldemort needs to be installed manually into the local maven repository as of the version 0.90.1.
According to the supplied tests, it looks fine. However, I need advice and suggestions to make it better,cleaner and right if there is something incorrect. I'll ask several questions that I got during the programming later.
Please let me know what you think of the code. If it's worth of a part of Hibernate OGM, I would like to contribute it.
Thank you
Seiya
12 years, 10 months