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
Re: [hibernate-dev] Where are the batched fetch statements generated?
by Clemens Eisserer
Hi Guenther,
>>> Is it possible to disable prepared statement caching for batched fetching, so I end up with a single query in the < default_batch_fetch_size case only >>instead of the
>>> fixed-size batch loading hibernate does by default?
> I think the main reason for no feedback so far, is that nobody was able to understand this sentence.
> Usually 'prepared statement caching' is a synonym to 'prepared statement pooling' and is something which has to be provided by a connection-pool (or a jdbc-driver) and thus
> Hibernate does actually not implement any prepared statement cache/pooling.
> Can you please explain what you intend under 'prepared statement caching'?
> Can you also please try to better explain the second part of your sentence?
Sorry for beeing that cryptic, I will try to rephrase it:
When Hibernate does batch-fetching, it generates PreparedStatements
for certain batch sizes - for a batch_size of 50, the prepared
statements for batch-sizes will have the following sizes:
[1,2,3,4,5,6,7,8,9,10,12,25,50]. When e.g. a batch of size 13 should
be fetched, because of the fixed size of the prepared statements, 3
queries are issued for batch-fetching, although 13 <= 50. In this case
the 3 batches would be of the size 13 = 8 + 4 + 1.
In a latency bound (between db and application) environment, this
serverly hampers response time - instead of a single round-trip to do
the batched fetch, Hibernate requires 3.
(subselect can't be used in my case, because my queries are already
rather complex, and the added complexity confuses the DBs query
planner too much)
What I did in this case (only for integer PKs) is to pad up to the
next batch size with a non-existant PK.
So, for the example mentioned above, I can use the PreparedStatement
with size 25, and insert padding from 14-25, which will make the query
slightly more inefficient but avoid 2 additioan round-trips.
- Clemens
12 years, 1 month
Fwd: Re: Proxies and typing
by Steve Ebersole
Forwarding a part of this discussion that got inadvertently limited to
just Sanne and myself.
Bringing this back up because this is most likely not going to be
accepted into JPA 2.1. Anyway, I am all for going down the path that:
public interface User {
...
}
@Entity
@Proxy(proxyClass=User.class)
public class UserImpl implements User {
...
}
means that users would use User.class in all phases of the API:
User user = session.byId( User.class ).get( 1 );
EntityType<User> jpaEntityType = emf.getMetamodel().entity(User.class );
etc.
I think that is the cleanest path that allows generic-typed api.
-------- Original Message --------
Subject: Re: [hibernate-dev] Proxies and typing
Date: Thu, 26 Jan 2012 14:37:22 +0000
From: Sanne Grinovero <sanne(a)hibernate.org>
To: Steve Ebersole <steve(a)hibernate.org>
On 26 January 2012 14:02, Steve Ebersole <steve(a)hibernate.org> wrote:
> These emails are just between you and me. Not sure if thats what you
> intended. I erroneously replied to just you at one point but then sent to
> whole list also. Anyway, just mentioning...
Ah, sorry, didn't notice either. Well last reply then, will try resume
the public conversation if I have more comments.
> The idea of requiring the interface is appealing in a way. But, for
> example, there are odd inconsistencies then. For example
>
> User user = session.byId( User.class ).get( 1 );
>
> but then
>
> EntityType<UserImpl> jpaEntityType = emf.getMetamodel().entity(
> UserImpl.class )
>
>
> Which I guess is my biggest hang up. On one side we are saying that the
> impl is the entity and on the other saying the interface is the entity.
>
> You know me and consistency :)
I agree on consistency, but this is tricky, I'm not sure if you need
the UserImpl at all, maybe you can remove it from the MetaModel (maybe
after having read out other metadata from it).
Isn't such a mapping definition like a dirty workaround to actually
map the interface ?
Sanne
12 years, 5 months
Pull request for HHH-2394 (Support filter tag in subclass)
by Rob Worsnop
https://github.com/hibernate/hibernate-orm/pull/339
It seemed that the challenge to overcome was that Hibernate did not
know which aliases to use when generating the where clauses for
filters. When filters are not allowed on subclasses (current
situation), the alias for the root entity is used for all where
clauses. So when FilterHelper is asked to render the filters, it does
so with a single alias string.
So my changes revolve around two themes:
1. Remembering the filter's associated table so that we can generate
an appropriate alias. This was done by replacing the name->condition
map with a list of FilterConfiguration objects. This is a new class
and includes a qualified table name (as well as the name and
condition, of course).
2. Passing a callback (instead of the alias string) to
FilterHelper.render() that allows it to generate an appropriate alias
for each filter, depending on table name. The callback is an
implementation of a new interface, FilterAliasGenerator. The
implementation varies by context.
Where filters are applied to entities, we know the table name. When
filters are applied to collections we do not. My solution to this is
potentially controversial and I'd be interested in hearing
alternatives to it. I have expanded the @Filter annotation to include
a table name. This is an optional element because it makes no sense
when @Filter is applied directly to an entity. That's what I don't
like about this idea.
For example:
@OneToMany(mappedBy="club")
@Filters({
@Filter(name="iqMin", table="ZOOLOGY_HUMAN", condition="HUMAN_IQ >= :min"),
@Filter(name="pregnantMembers", table="ZOOLOGY_MAMMAL",
condition="IS_PREGNANT=1")
})
private Set<Human> members = new HashSet<Human>();
This is excerpted from here:
https://github.com/rworsnop/hibernate-orm/blob/HHH-2394/hibernate-core/sr...
Thoughts?
12 years, 5 months
Quoted names
by Dmitry Geraskov
Hi, guys,
I am working on the hibernate tools code generation problem for tables
which has quoted names (name, schema or catalog has special symbols(dot
for ex.)).
Any reason why Table#setName(x) and Table#setSchema(x) have "unquote"
logic, but Table#setCatalog(x) does not?
Dmitry Geraskov
12 years, 6 months
Hibernate Search Question
by Christian Beikov
Hello!
I just looked into the Hibernate Search source code and was wondering
why you are using hibernates criteria API instead of JPA Criteria API? I
haven't looked deeper but actually this is the reason why it can't be
used with other JPA implementations, or are there any other dependencies
to hibernate specifc code? From a performance perspective it is probably
a bad idea to use JPA Criteria API, but if no really special
dependencies to the hibernate core code are needed to make it working
why not adapting it to JPA?
I would like to help to make it usable with other JPA implementations(at
least if it is possible)!
--
Mit freundlichen Grüßen,
------------------------------------------------------------------------
*Christian Beikov*
12 years, 6 months
[OGM] [Neo4J] AssociationKey and missing info for associations mapping
by Pawel Kozlowski
hi!
I'm progressing on the implementation of the Neo4j integration for
Hibernate OGM and I think that I've bumped into a missing piece of
info when mapping associations.
Let me explain: in Neo4j (in any grap database really) it would be
very natural to map an association of 2 entities as a relationship
among 2 nodes (where each node represents an entity). This was the
path I was taking but then I've realized that I'm probably missing a
piece of info that would allow me to connect 2 nodes together.
Looking at the OGM docs and debugging I've realized that (at least
today) I've got only following pieces of info available in the
AssociationKey:
- table name for the association owning entity
- a set of column names / column values corresponding to a primary key
of the target entity.
Moreover, 'columnNames' in AssociationKey got a predefined names in
form of [o:property name]_[t:pk_field1], [o:property
name]_[t:pk_field2] etc. (where 'o' stands for the owning entity and
't' for the target one).
What I would like to (ideally) do is to map an association as a Neo4j
relationship between 2 nodes (each node corresponding to an entity)
where the relationship would be named as [o:property name].
Unfortunately I'm facing 2 issues:
1) I don't have access to EntityKey's of 2 ends of the association (or
at least I don't know how to access this info). I've noticed that
Emmanuel works on providing a valid EntityKey inside a AssociationKey
(https://github.com/emmanuelbernard/hibernate-ogm/tree/OGM-177) - I
guess it would solve half of my problems :-)
2) Naming strategy of column names in AssociationKey ([o:property
name]_[t:pk_field1]) makes it difficult to get a hand on a [property
name] - I would like to avoid splitting on '_' as it is very fragile.
I'm still quite new to Hibernate OGM so I'm not sure if I'm
approaching the problem from the right angle. I would really like to
keep mapping as natural to Neo4j / graph DB way of thinking so I would
be grateful for any feedback.
Cheers,
Pawel
12 years, 6 months
Various "row value construct" alike syntax and Dialect class
by Łukasz Antoniak
Hello Community,
Really quick question. There are quite few SQL syntax tricks similar to "row value construct".
CREATE TABLE test ( a1 NUMBER, b1 NUMBER );
SELECT * FROM test WHERE (a1, b1) = ( 1, 1 ); -- Fails on Oracle
SELECT * FROM test WHERE (a1, b1) IN ( ( 1, 1 ), ( 2, 2 ) ); -- Passes on Oracle
SELECT * FROM test WHERE (a1, b1) = ( SELECT 1, 1 FROM dual ); -- Passes on Oracle
SELECT * FROM test WHERE (a1, b1) IN ( SELECT 1, 1 FROM dual ); -- Passes on Oracle
Oracle does not support "row value syntax" as shown in the first query (Dialect#supportsRowValueConstructorSyntax() has to return
false).
Should I assume that second, third and fourth query ought to pass when Dialect#supportsRowValueConstructorSyntaxInInList() returns
positive? Or shall I add another method to Dialect class like supportsRowValueConstructorSyntaxInSelectList()? Please advise. I
just do not want the Dialect class to grow and grow. Dialect#supportsRowValueConstructorSyntaxInInList() is overridden only by
Oracle dialect, but PostgreSQL supports this feature as well.
Regards,
Lukasz Antoniak
12 years, 7 months