Re: [hibernate-dev] Overriding JpaMergeEventListener with JpaEntityCopyAllowedMergeEventListener
by Gail Badner
CC'ing hibernate-dev...
----- Original Message -----
> From: "Gail Badner" <gbadner(a)redhat.com>
> To: "Steve Ebersole" <steve(a)hibernate.org>, "Emmanuel Bernard" <emmanuel(a)hibernate.org>
> Sent: Friday, June 20, 2014 4:25:56 PM
> Subject: Overriding JpaMergeEventListener with JpaEntityCopyAllowedMergeEventListener
>
> I am trying into figure out how to override JpaMergeEventListener with
> JpaEntityCopyAllowedMergeEventListener as described in [1]. This
> documentation does not describe how to deal with injecting CallbackRegistry
> into an overridden MergeEventListener.
>
> CallbackRegistry is an SPI, but JpaMergeEventListener and
> CallbackRegistryConsumer are internal.
> JpaEntityCopyAllowedMergeEventListener is also internal.
>
> I was planning to document MyIntegrator.integrate(..) for enabling entity
> copies, but I don't like the idea of documenting an internal event listener
> for that functionality.
>
> Here is one alternative that minimizes exposing private classes/methods:
>
> public class MyIntegrator implements org.hibernate.integrator.spi.Integrator
> {
>
> public void integrate(
> Configuration configuration,
> SessionFactoryImplementor sessionFactory,
> SessionFactoryServiceRegistry serviceRegistry) {
> final EventListenerRegistry eventListenerRegistry =
> serviceRegistry.getService( EventListenerRegistry.class );
> final MergeEventListener mergeEventListener =
> mergeEventListenerGroup.listeners().iterator().next();
> final JpaEntityCopyAllowedMergeEventListener
> entityCopyAllowedMergeEventListener =
> new JpaEntityCopyAllowedMergeEventListener();
> entityCopyAllowedMergeEventListener.initializeFrom(
> mergeEventListener );
> registry.setListeners( EventType.MERGE,
> entityCopyAllowedMergeEventListener );
> }
> ...
> }
>
> public class JpaEntityCopyAllowedMergeEventListener extends
> JpaMergeEventListener {
> ...
> public void initializeFrom(MergeEventListener mergeEventListener) {
> if ( JpaMergeEventListener.class.isInstance( mergeEventListener ) ) {
> injectCallbackRegistryFrom( (JpaMergeEventListener)
> mergeEventListener );
> }
> }
> ...
> }
>
> public class JpaMergeEventListener extends DefaultMergeEventListener
> implements CallbackRegistryConsumer {
> ...
> protected void injectCallbackRegistryFrom(JpaMergeEventListener
> jpaMergeEventListener) {
> injectCallbackRegistry( jpaMergeEventListener.callbackRegistry );
> }
> ...
> }
>
> Another alternative is to change JpaEntityCopyAllowedMergeEventListener to be
> a Proxy that holds an instance of the original JpaMergeEventListener.
> Everything except for createEntityCopyObserver() could be delegated to the
> stored JpaMergeEventListener. There would be no need to call
> injectCallbackRegistry(CallBackRegistry).
>
> It might be possible to have one Proxy for
> JpaEntityCopyAllowedMergeEventListener and
> EntityCopyAllowedMergeEventListener holding an instance of
> MergeEventListener, but that Proxy wouldn't implement
> CallbackRegistryConsumer or HibernateEntityManagerEventListener. Does that
> matter for an overridden event listener if the CallbackRegistry does not
> have to be injected?
>
> Is there some other way of doing this that I've missed?
>
> Thanks,
> Gail
>
> [1]
> http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch07.html#reg...
>
>
10 years, 2 months
Apache Lucene 4.9 is coming
by Sanne Grinovero
Hi all,
there is quite a list of changes:
http://people.apache.org/~rmuir/staging_area/lucene_solr_4_9_0_r1604085/l...
some are good and nice bugfixes, but there is yet again quite a list
of API / behaviour changes which affect us:
- AttributeSource API
- Directory API (requires Infinispan updates first)
- MergePolicy API (we have our custom ones)
- IndexWriter.delete methods changed
- DocIdSet changed interface hierarchy
- IndexWriterConfig no longer supports cloning, we'll need an
efficient factory to rebuild these
- IOContext has been added to various methods as mandatory parameter
I'm overall not happy to see so many changes, but I believe we need to
keep up so my vote is to upgrade.
The best reason is a method drop in the Directory API, which is no
longer needed, and was making it very hard to squeeze reasonable
performance out of Infinispan. This method being gone now is very
welcome: it required us to do double-buffering to implement the
checksum functionality which was introduced in Lucene 4.8.
Sanne
10 years, 2 months
[Search] Index embedded and id property of embedded entity
by Hardy Ferentschik
Hi,
I started to look at HSEARCH-1494 [1] which deals with an unexpected exception is thrown when @IndexedEmbedded is used.
Easiest to explain with an example:
@Entity
@Indexed
public class A {
@Id
@GeneratedValue
private long id;
@OneToOne
@IndexedEmbedded
private B b;
}
@Entity
public class B {
@Id
@GeneratedValue
private Timestamp id;
@Field
private String foo;
public Timestamp getId() {
return id;
}
public String getFoo() {
return foo;
}
}
A includes B via @IndexedEmbedded and is only interested in including the ‘foo’ field. However, atm we implicitly index B.id as well.
In this particular case an exception is thrown, because we don’t know which field bridge to use for B.id.
This also relates to HSEARCH-1092 [2], where the include path feature of @IndexedEmbedded is used. Even though the configured
paths don’t include the ids, they are added which increases the index size unnecessarily (not really sure whether it really matters in practice).
If we skip the implicit inclusion of id properties, the user will need to add an explicit @Field in case he wants to include an id property via indexed
embedded. If the embedded entity itself is not indexed, I think this makes sense. But what if the embedded entity is indexed itself? Does it seem
wrong in this case to specify an additional @Field? Do we need some additional configuration element?
Thoughts?
—Hardy
[1] https://hibernate.atlassian.net/browse/HSEARCH-1494
[2] https://hibernate.atlassian.net/browse/HSEARCH-1092
10 years, 2 months
Making tests nicer with lambdas
by Gunnar Morling
Hey,
I've played around a bit with the idea of using Java 8 lambdas to make
tests easier to write and read. We have many tests which open a session and
TX, do some stuff, commit, open a new TX (and/or session), do some
assertions and so on:
Session session = openSession();
Transaction transaction = session.beginTransaction();
// heavy testing action...
transaction.commit();
session.clear();
transaction = session.beginTransaction();
// load, assert...
transaction.commit();
session.clear();
The same could look like this using Java 8 lambdas:
Foo foo = inTransactionWithResult( (session, tx) -> {
// heavy testing action...
} );
inTransaction( (session, tx) -> {
// load, assert...
} );
Extracting the session/TX handling removes quite some clutter and focuses
more on the actual testing logic. It also avoids problems due to dangling
transactions e.g. in case of assertion failures as the TX handling is done
in a finally block in inTransaction().
At this point I've just done a quick POC and would be interested in
feedback whether you think that's worth pursuing or not. Note that
different language levels can be used for test and main code, so we could
make use of lambdas in tests while ensuring Java 6 compatibility for the
delivered artifacts.
--Gunnar
10 years, 2 months
Reflite
by Steve Ebersole
I am curious about people's take on "reflite" now that some of y'all have
had a chance to see it in action.
Some specific points I am curious about (although certainly feel free to
comment on any parts):
1) What do you think of the split in JavaTypeDescriptor into distinct
sub-contracts? For example, the split between say ClassDescriptor and
InterfaceDescriptor? TBH, I am starting to rethink that one. What about
primitive versus non-primitive descriptors? Etc...
2) Overall what do you think about the API itself? Don't worry about the
internal details. For example, the need to access the ClassLoader (to walk
the fields/methods) is hopefully going away with some additions to Jandex.
But in terms of the exposed contracts
(org.hibernate.metamodel.reflite.spi)...
10 years, 3 months
Envers: Mapped-superclasses extended by embeddabables
by Gail Badner
Hi Adam,
The relevant issues:
HHH-8908 : Envers: Column of Embedded missing in Audit Table
HHH-9194 : Revert HHH-8908 fix
HHH-9193 : Default audit behavior of a mapped-superclass is inconsistent when extended by an entity vs an embeddable
I created a pull request for reverting HHH-8908 (https://github.com/hibernate/hibernate-orm/pull/742). The fix is reverted for HHH-9194 and I've re-purposed the testcases that were added to HHH-8908 for HHH-9193. I'm still a little fuzzy of the expectations of these tests, so please take a look at the pull request and let me know if anything needs to be changed.
I'm still unsure how on the ways to explicitly enable auditing for a mapped-superclass as a whole or particular fields/methods. Here are some guesses on how I think it should work. Assume the following uses AccessType.FIELD.
In the following, A.b.intValue should be audited; A.b.strValue should not be audited.
@Entity
@Audited
public class A{
...
private B b;
...
}
@Embeddable
public class B extends AbstractB {
private int intValue;
}
@MappedSuperclass
public class AbstractB {
private String strValue;
}
In the following, both A.b.intValue and A.b.strValue should be audited:
@Entity
@Audited
@AuditOverride( name="b.strValue" )
public class A{
...
private B b;
...
}
@Embeddable
public class B extends AbstractB {
private int intValue;
}
@MappedSuperclass
public class AbstractB {
private String strValue;
}
In the following, both A.b.intValue and A.b.strValue should be audited:
@Entity
@Audited
public class A{
...
private B b;
...
}
@Embeddable
public class B extends AbstractB {
private int intValue;
}
@MappedSuperclass
@Audited
public class AbstractB {
private String strValue;
}
In the following, both A.b.intValue and A.b.strValue should be audited.
@Entity
@Audited
public class A{
...
private B b;
...
}
@Embeddable
@AuditOverride( class=AbstractB.class )
public class B extends AbstractB {
private int intValue;
}
@MappedSuperclass
public class AbstractB {
private String strValue;
}
What should be the outcome of the following? Should A.b.strValue still be audited even though A.b is explicitly not audited?
@Entity
@Audited
public class A{
...
@NotAudited
private B b;
...
}
@Embeddable
public class B extends AbstractB {
private int intValue;
}
@MappedSuperclass
@Audited
public class AbstractB {
private String strValue;
}
Please clarify or correct as necessary. At this point, I'm not sure which of the above cases work. Once the expected behavior is clarified, tests should be added to ensure that envers operates as expected. Jira issues should be added for cases that don't work.
Thanks,
Gail
10 years, 3 months