Shortcomings in org.hibernate.id.enhanced.TableGenerator class
by Tom Muldoon
I'm working with the org.hibernate.id.enhanced.TableGenerator class and I've noticed a couple of shortcomings (imho). First and foremost, it creates one row in the hibernate_sequences table for each configured segment_value (as opposed to one row for each "target_table" as implemented within the MultipleHiLoPerTableGenerator). Given the fact that my id column is defined in an abstract BaseEntity class, I can't use the enhanced TableGenerator class as is (since one sequence for all of my entities is not viable for my application). Which leads me to my second point. All of the member variables are declared as private, instead of protected, which makes extending the class for the purpose of overriding the configure method impossible.
For what it's worth, here's the change that I had planned to make (in the configure method) ...
Change the setting of the segmentValue from ...
segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
... to
segmentValue = params.getProperty(TABLE);
Of course, such a change would change the class behavior significantly - using targetTable instead of segmentValue as the variable name would probably make sense.
So, with that said, is another class worth-while (assuming that such a change to the existing class would break backwards compatability)?
And, on a related note, the enhanced TableGenerator is cluster safe, right?
Thoughts?
PS. I entered a jira improvement yesterday - here's the link ...
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3249
16 years, 5 months
hibernate-documentation CI job
by Aleksandar Kostadinov
Hallo,
This mail is to announce the newly created hibernate-documentation job.
It is now setup to run daily. Let me know if you want artifacts deployed
on some repository as now it doesn't deploy anywhere.
Thanks,
Aleksandar
16 years, 5 months
Hibernate Search: Master/Slave DirectoryProviders improvements proposal
by Sanne Grinovero
Hello most esteemed developers,
I have been scrutinizing the FSMasterDirectoryProvider and
FSSlaveDirectoryProvider
classes in Hibernate Search and have found some minor glitches and space
for some improvement (IMHO); I would like to hear your opinion about it,
and if you agree I'll open a JIRA and provide a patch myself ASAP.
A) Variable visibility
both FSMasterD.P. and FSSlaveD.P. have some little concurrency problems:
there is a "volatile boolean inProgress" that fixes the communication beetween
the "CopyDirectory" Runnable and the "TriggerTask" Timer, but all comunication
beetween the client thread calling "getDirectory()" and the CopyDirectory
which defines the current directory is unprotected; also volatile isn't enough
to fix it, IMHO an AtomicReference would be more appropriate.
The locking schema looks great! I've had a hard time understanding the flow
and did some tests about the behaviour of Lucene in case of concurrent
index-deletion and forcing the most dangerous situations I could think of,
I couldn't find anything failing.
Actually in the current situation the lock works ok but the wrong Directory
could be returned because of the visibility problems; the lock avoids most
problems but could hurt scalability (as we could return locked resources even
whenever an unlocked dir was available).
B) The finalize / stop issue
Also I would like to address the use of finalize() to stop the Timer,
there is a TODO about it already; IMHO the best solution is to remove
the finalize without changing other code: the Timer is declared as
daemon thread already, so it's going to stop automatically on JVM exit.
The current finalize idea could harm the GC, as in the finalize we are
referencing
the timer and instruct the timer to do something: the timer has a reference
to <this> so this would revive the reference to <this> and cancel the
garbage-collection;
actually I don't think this finalizer is ever being called, as the timer
also has a reference to this (being an inner class) and is running in another
thread which is certainly alive (as our purpose was to
stop it and we we still didn't get to that point).
So we could fix this issues just removing code, and making some instance
variables (such as the Timer itself) unnecessary.
Also this means you won't need a stop() to be added to
DirectoryProvider interface,
at least not for FSMasterD.P. and FSSlaveD.P. ( which are the only
known implementations
needing it, so we could also remove the TODO in the DirectoryProvider.
C) FileHelper not listening to Thread.interrupt() requests
As FileHelper.synchronize is used in the mentioned Timers to copy
potentially big files,
it would be nice to check for Thread.isInterrupted() and also catch
ClosedByInterruptException in file-copy operations so to abort all I/O
operations and
not just the current one to abort faster on JVM shutdown.
(It doesn't look like the copy safety was guaranteed anyway).
D) Master and Slave share configuration properties.
Wouldn't it be natural to have two different property keys to manage
the shared index path? I imagine the typical scenario would be to have the two
configured on different servers and copy through some NFS, but it looks like
we are forcing people to use exactly the same path on both machines as the two
classes read the same props.
kind regards,
Sanne
16 years, 5 months
Shortcomings in org.hibernate.id.enhanced.TableGenerator class
by Tom Muldoon
I apologize if this is a 2nd posting.
________________________________
From: hibernate-dev-bounces(a)lists.jboss.org [mailto:hibernate-dev-bounces@lists.jboss.org] On Behalf Of Tom Muldoon
Sent: Thursday, April 24, 2008 8:04 AM
To: 'hibernate-dev(a)lists.jboss.org'
Subject: [hibernate-dev] Shortcomings in org.hibernate.id.enhanced.TableGenerator class
I'm working with the org.hibernate.id.enhanced.TableGenerator class and I've noticed a couple of shortcomings (imho). First and foremost, it creates one row in the hibernate_sequences table for each configured segment_value (as opposed to one row for each "target_table" as implemented within the MultipleHiLoPerTableGenerator). Given the fact that my id column is defined in an abstract BaseEntity class, I can't use the enhanced TableGenerator class as is (since one sequence for all of my entities is not viable for my application). Which leads me to my second point. All of the member variables are declared as private, instead of protected, which makes extending the class for the purpose of overriding the configure method impossible.
For what it's worth, here's the change that I had planned to make (in the configure method) ...
Change the setting of the segmentValue from ...
segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
... to
segmentValue = params.getProperty(TABLE);
Of course, such a change would change the class behavior significantly - using targetTable instead of segmentValue as the variable name would probably make sense.
So, with that said, is another class worth-while (assuming that such a change to the existing class would break backwards compatability)?
And, on a related note, the enhanced TableGenerator is cluster safe, right?
Thoughts?
PS. I entered a jira improvement yesterday - here's the link ...
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3249
16 years, 5 months
Re: [Hibernate-JIRA] Commented: (HSEARCH-115) Add a default value for indexing null value
by Sanne Grinovero
some inline comments:
2008/4/22, Hardy Ferentschik <hibernate(a)ferentschik.de>:
> On Tue, 22 Apr 2008 03:29:18 +0200, Sanne Grinovero
> <sanne.grinovero(a)gmail.com> wrote:
>
>
> > A new proposal:
> > I got inspired by the "3VL" considerations described in Emmanuel's
> > link to wikipedia, and think backwards compatibility is nice:
> > add a "@IndexNullMarker" on the property, this will add an additional
> > Field to the index for null values:
> >
>
> Hmm, interesting idea. It addresses one of the biggest concerns I have
> with this null marker thing, namely ambiguities. But would querying look
> like in this
> case. Wouldn't it become harder? Whenever you want to use this feature you
> would have
> to combine two fields - foo and fooIsFalse - within a boolean query to get
> the expected
> result. Something like this: "foo:bar OR fooIsNull:true".
Yes right but I don't see how this is worse than searching for
"foo:bar OR foo:NULL-KEYWORD", just some less ambiguity.
If you just want to search for null fields, fooIsNull:true
> Of course it would also mean that the index size grows since we are adding
> more fields.
> And the bigger the index, ...
Interesting I wasn't expecting the index to grow as I remove a Field
and replace it with another; I've made a test for this: on 10,000,000
docs having 50% a random text value (chosen from 800 constants to
limit total string tokens) and 50% nulls the index
size grows by 3.5% compared to no null values (same docs and 800 consts).
I wasn't expecting any growth above some bytes, anyway I think 3.5% is
quite good.
>
>
> > The Field and StringBridge API would remain as-is;
> > If you prefer not to add an additional @IndexNullMarker could be
> > dropped if you think adding this field is acceptable for all fields.
> >
> I think it should stay an optional and explicit feature. Adding one
> addtional field for
> each indexed properties does not seem justified. Especially, since we agree
> that
> the best solution would be to re-think your design and come up with a
> proper
> non-null default. So by offering this feature we might end up encouraging
> people
> to stick with there less optimal design ;-)
Absolutely agree, default is disabled. But I hope it will be possible
to log an explicit error if someone tries to use the field (without
enabling this feature) with the "NullQuery" Emmanuel proposed.
>
> Cheers,
> Hardy
>
Regards,
Sanne
16 years, 5 months
Re: [Hibernate-JIRA] Commented: (HSEARCH-115) Add a default value for indexing null value
by Emmanuel Bernard
Hey
The more I think about the feature, the less I like it.
Here is what I have written in Hibernate Search in Action
Hibernate Search, by default, does not store null attributes into the
index. Lucene does not have the notion of null fields, the field is
simply not there. Hibernate Search could offer the ability (and most
likely will in the future) to use a special string as a null marker to
still be able to search by "null".
But before you jump at the Hibernate Search team throat, you need to
understand why they have not offered this feature so far. Null is not
a value per se. Null means that the data is not known (or does not
make sense). Therefore, searching by null as if it was a value is
somewhat odd. The authors are well aware that this is a raging debate
especially amongst the relational model experts (see http://en.wikipedia.org/wiki/Null_%28SQL%29)
.
Whenever you feel the need for searching by "null", you should ask
yourself if storing a special marker value in the database would make
more sense. If you store a special marker value in the database, a lot
of the "null" inconsistencies vanish. It also has the side effect of
being queriable in Lucene and Hibernate Search.
So before we jump on the boat for this feature, I would like to know
if people think it's still a good idea to offer this feature.
To answer your questions, the reason why I do not pass @Field but the
raw set of data is because the @Field.index is translated into it's
Lucene representation: some work is done.
Most people will write StringBridge implementation anyway where the
null handling will be taken care of transparently (by
String2FieldBridgeAdaptor).
I think I like 1 or 3. Note that get should be changed as well. Three
is interesting indeed, rename it IndexingStragegy.
On Apr 21, 2008, at 10:07, Hardy Ferentschik wrote:
> Hi Emmanuel,
>
> what's you take on this? Just adding another String parameter will
> work, but are we not getting too many parameters into the method?
> Wouldn't it be nicer to pass the actual @Field annotation. I think
> this might make things also clearer for the implementor of the
> interface.
>
> I am also trying here to get a little into your head to understand
> your ideas behind the code design - hope
> you don't mind ;-)
>
> --Hardy
>
>
>
> ------- Forwarded message -------
> From: "Hardy Ferentschik (JIRA)" <noreply(a)atlassian.com>
> To: hardy(a)ferentschik.de
> Subject: [Hibernate-JIRA] Commented: (HSEARCH-115) Add a default
> value for indexing null value
> Date: Mon, 21 Apr 2008 14:04:33 +0200
>
>
> [ http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-115?pag...
> ]
>
> Hardy Ferentschik commented on HSEARCH-115:
> -------------------------------------------
>
> Ok, here are a few suggestions:
>
> 1. This is the simplest way. Basically just add a new property named
> 'indexNullAs' to @Field and @ClassBridge. Accordingly extend the
> FieldBridge interface to set(String name, Object value, Document
> document, Field.Store store, Field.Index index, Field.TermVector
> termVector, Float boost, String indexNullAs).
>
> 2. Alternatively one could change the FieldBridge API to actually
> pass in the Field annotation itself: set(String name, Object value,
> Document document, Field fieldAnnotation, Float boost). This would
> reduce the amount of parameters and might actually be more
> transparent for users implementing custom bridges. Unfortunately,
> one would have to introduce a ClassBridge interface as well in this
> case. I am not sure whether it is a good design choice to pass
> annotation instances around.
>
> 3. We ccould also change the API into something like this:
> set(String name, Object value, Document document, IndexProperties
> props), where IndexProperties is just a wrapper class for
> Field.Store, Field.Index, ... The drawback is that this just
> increases the number of classes.
>
> Any comments?
>
>> Add a default value for indexing null value
>> -------------------------------------------
>>
>> Key: HSEARCH-115
>> URL: http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-115
>> Project: Hibernate Search
>> Issue Type: Improvement
>> Components: mapping
>> Reporter: Julien Brulin
>> Assignee: Hardy Ferentschik
>> Fix For: 3.1.0
>>
>>
>> Hi,
>> Null elements are not indexed by lucene then it's not easy to use a
>> nullable property in lucene query.
>> I have a TagTranslation entity in my model with a nullable property
>> language. In this case null is used as default language for tag
>> translation.
>> Each translation may have many variations like synonyms.
>> Because I can specified a default value for null value in the
>> @Field annotation like this @Field(index=Index.UN_TOKENIZED,
>> store=Store.NO, default='null'), i can't search a cat tag with a
>> default translation like this : +value:cat* +lang:null
>> <pre></code>
>> @Entity()
>> @Table(name="indexing_tag_trans")
>> @org
>> .hibernate
>> .annotations
>> .Cache
>> (usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
>> @Indexed
>> public class TagTranslation implements java.io.Serializable {
>>
>>
>> private static final long serialVersionUID = -1065316566731456110L;
>>
>> @Id
>> @GeneratedValue(strategy=GenerationType.IDENTITY)
>> @DocumentId
>> private Integer id;
>>
>> @Field(index=Index.UN_TOKENIZED, store=Store.NO)
>> private String language;
>>
>> @Field(index=Index.TOKENIZED, store=Store.YES)
>> private String value;
>>
>> @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
>>
>> @org
>> .hibernate
>> .annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
>> @JoinColumn(name="translation_id")
>> @IndexedEmbedded
>> private List<TagVariation> variations = new
>> LinkedList<TagVariation>();
>>
>> public TagTranslation() { }
>> ...
>> </code>
>> </pre>
>> What do you think about that ?
>> Ps: sorry for english write, i am a french guy.
>
>
>
> --
> Hartmut Ferentschik
> Ekholmsv.339 ,1, 127 45 Skärholmen, Sweden
> Phone: +46 704 225 097 (m)
16 years, 5 months
Pagination: An approach for retrieving results / page count in single query
by Jonathan Gerrish
[Already posted to hibernate-users, but no responses.]
Hi,
I have pagination working, but am doing so with two queries; one to get the
results page and a second one to get the total count.
I'd like to do this in a single query: Is it possible to build a criteria,
so my results set includes columns for each of the properties on my bean,
plus an additional column which has the row count (downside: this is
duplicated for each row in the page).
I figured I could build a projection like this to return all the beans
properties plus the row count.
private Projection getProjectionsForBeanAndRowCount() {
ClassMetadata classMetadata =
session().getSessionFactory().getClassMetadata(modelClass);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.rowCount());
String[] propertyNames = classMetadata.getPropertyNames();
for (String propertyName : propertyNames) {
projectionList.add(Projections.property(propertyName));
}
return projectionList;
}
..and then write a ResultsTransformer to process these results,
instantiating a class like:-
public class PageResult {
Object bean;
int rowCount;
}
..but it seems that by the time ResultsTransformer is called, you already
have the bean instantiated.
Is there a way I can jump in at a slightly lower level, like at a single row
of the result set, the level where the results bean's are built?
Any info much appreciated.
All the best, Jon
16 years, 5 months
Acceptance Of Documentation Patches
by Jason Ferguson
Recently, I've been trying to figure out how to create
ResultTransformers, Interceptors, Listeners, etc (don't worry, this
isn't me asking for help). Unfortunately, the documentation for those
items is somewhat lacking.
While I have been guilty of the "first make it work, then (if you have
time) make it pretty" (or my boss has told me to do that), I'm not
really the type to gripe and whine. I'd be fine with actually pitching
in to do the work.
However, this leads to my question: if I do the work (and its of
acceptable quality), and submit it in the JIRA as a patch, will it be
accepted?
(I'm desperately trying not to sound rude or obnoxious... if my tone
is interpreted as negative, please accept my apologies in advance.)
Jason
16 years, 5 months
HIbernate Behavior Persisting Lists.
by Wesley Forti
Hi
I´d like to know how hibernate manage list persistene. Let me explain.
I have a Table in my DB and a List in my java code representing my data
persisted in DB. Imagine user made some manipulating in this list: remove
some object, add new one and edited existing ones.
How hibernate persists this data back to DB? It will delete all data in DB
an persist all my list back again?
How does it make this merge?
tk´s.
--
Att,
---
Wesley Forti
16 years, 6 months