Is org.hibernate.cache.spi.OptimisticCacheSource#getVersionComparator obsolete?
by Gail Badner
It is implemented by AbstractEntityPersister, but as of 5.0.9 (using
Infinispan 7.2.5.Final) I see no references to this method in Hibernate
ORM, other than in Javadoc for OptimisticCacheSource#isVersioned [1] that
says:
"If true, it is illegal for {@link #getVersionComparator} to return null"
[1]
Long story short, if OptimisticCacheSource#getVersionComparator is
obsolete, then there is no reason to create a meaningful Comparator for
Sybase timestamps for HHH-10413.
The long story...
Sybase timestamp can be used as an entity version which is treated as
byte[]. This seems to have caused problems in the past when caching,
because an array does not have a Comparator.
I tried creating a simple comparator that uses Byte#compareTo(Byte), but
unfortunately this does not work for Sybase timestamps, because
Byte#compareTo(Byte)
uses a signed comparison. Sybase timestamps require an unsigned comparison.
I can change the comparator to do unsigned comparisons of byte elements.
One thing to consider is that the same comparator will also be used for
when sorting actions by byte[] IDs.
We discussed earlier that it doesn't make sense to compare IDs that are
arrays. If
OptimisticCacheSource#getVersionComparator is obsolete, then I can simply
use IncomparableComparator#INSTANCE.
If OptimisticCacheSource#getVersionComparator is not obsolete, then is it
worth creating a special BinaryTimestampType that implements
VersionType<byte[]> (instead of BinaryType implementing
VersionType<byte[]>) with a comparator that does unsigned comparisons?
I'm also trying to wrap up HHH-8999, which is also impacted by this.
Regards,
Gail
[1]
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src...
9 years, 6 months
Java 9: progress on compatibility
by Sanne Grinovero
Hi all,
please try to have a look at this page when you have a moment:
- http://ci.hibernate.org/view/JDK9/
Hibernate Search is working, and it shouldn't be too hard to get the
others "green" as well.
I've disabled some integration tests to get there, notably:
- OSGi tests: Karaf is not ready for it.
- Documentation build: Asciidoc will probably need an update.
- WildFly integration tests: the WildFly team is aware, will need a
minor upgrade.
I don't believe these issues are relevant, so I'm satisfied that all
other tests working fine mean that the project will pretty much work
out of the box for end users - at worst their container won't work,
but that's not our responsibility to test for.
Could you all contribute a bit to get all projects show "green" on this page?
Some "workarounds" you might want to apply:
- the Logger interfaces won't compile because of a known issue, this
can be worked around for now by having the compilation phase also
explicitly depend on this artifact:
https://github.com/hibernate/hibernate-search/blob/master/pom.xml#L878-L883
- you'll have a ClassNotFoundException on JAXB usage unless you set
this JVM flag: https://github.com/hibernate/hibernate-search/blob/master/pom.xml#L1429
(This one is not a bug but will be required to be set by end users as
well - or we provide our own XML parser, that might be more user
friendly).
As far as I know, other issues with the build tools have been solved
already - including Gradle.
Thanks,
Sanne
9 years, 6 months
Cleaning up non final versions from download pages
by Emmanuel Bernard
I've cleaned up the non final versions of OGM 5.0 from the website
download pages.
There is a displayed: false flag on the yml release document.
I could not find any reason why the alpha, beta and cr were shown in the
list.
Emmanuel
9 years, 6 months
Handling connections properly during testing with Java 1.8
by Vlad Mihalcea
Hi,
Now that we moved to Java 1.8, would you like to add a task so that we
manage the Session/Transaction automatically using a test utility like the
ones I added in the documentation tests:
doInHibernate( this::sessionFactory, session -> {
Person person = new Person();
person.id = 1L;
session.persist( person );
person.phones.add( "027-123-4567" );
person.phones.add( "028-234-9876" );
session.flush();
person.getPhones().remove( 0 );
} );
Or for JPA:
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( 1L );
entityManager.persist( person );
person.addPhone( new Phone( 1L, "landline", "028-234-9876" ) );
person.addPhone( new Phone( 2L, "mobile", "072-122-9876" ) );
entityManager.flush();
person.removePhone( person.getPhones().get( 0 ) );
} );
1. The tests will be less verbose.
2. There are times when a test fails on MySQL and then the suite stops
because the connection is not closed properly and the DROP command hangs.
What do you think?
Vlad
9 years, 6 months
Revert API change in org.hibernate.Query
by Sanne Grinovero
I just noticed that the org.hibernate.Query interface was deprecated
in 5.2, with the suggestion to use org.hibernate.query.Query now.
That's ok, but it seems the "deprecation process" also forced some API
changes already on the deprecated interface which seem might have been
unintentional.
The builder methods on org.hibernate.Query used to allow returning
"this" to chain methods,
although this seems no longer possible as the API now declares the
return type should be the new one, org.hibernate.query.Query.
Could we fix this by relaxing the return to the older deprecated method?
in practice:
org.hibernate.query.Query<R> setFirstResult(int startPosition);
should be:
org.hibernate.Query<R> setFirstResult(int startPosition);
Thanks,
Sanne
9 years, 6 months
5.2 or 6.0
by Steve Ebersole
Currently we are still working on 6.0 "on top" of 5.2, meaning that all of
the changes we are proposing to ORM for 6.0 are kept in a separate
repo/project using ORM 5.2 as a dependency.
As I work on 6.0 I have come across a change that I would like to make that
requires that I change something in ORM proper. The specific change is
that I would like to remove static access
to org.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry
and org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry and have
these scoped as part of the SessionFactory instead (technically as part of
the org.hibernate.metamodel.internal.MetamodelImpl associated with a
SessionFactory).
There are 2 ways I can go about this:
1. branch 5.2 and start 6.0 dev on master
2. make this change in master for inclusion in both 5.2 and 6.0
(2) is certainly the more convenient approach. But even beyond convenient,
I have seen some bugs from the fact that these are statically typed -
theoretically they should be scoped to the SF since the SF can mutate them.
However making that change in 5.2 has some risks depending upon whether
apps/integrations use it. Anyone aware of any integration(s) accessing
these 2 registries?
9 years, 6 months
Collection was not processed by flush()
by Petar Tahchiev
Hello,
I'm using hibernate version 5.1.0.Final and spring-data-rest and I have a
StockRepository which is exposed via rest and when I try to create a new
stock entry I get the following exception:
2016-06-05 17:02:43,917 org.hibernate.AssertionFailure
[http-nio-127.0.0.1-8112-exec-2] ERROR: HHH000099: an assertion failure
occured (this may indicate a bug in Hibernate, but is more likely due to
unsafe use of the session): org.hibernate.AssertionFailure: collection [
com.nemesis.platform.module.commerce.core.entity.i18n.CurrencyEntity.name]
was not processed by flush()
2016-06-05 17:02:43,920
org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/storefront].[repositoryRestDispatcherServlet]
[http-nio-127.0.0.1-8112-exec-2] ERROR: Servlet.service() for servlet
[repositoryRestDispatcherServlet] in context with path [/storefront] threw
exception [Request processing failed; nested exception is
org.springframework.transaction.TransactionSystemException: Could not
commit JPA transaction; nested exception is
javax.persistence.RollbackException: Error while committing the
transaction] with root cause
org.hibernate.AssertionFailure: collection [
com.nemesis.platform.module.commerce.core.entity.i18n.CurrencyEntity.name]
was not processed by flush()
at
org.hibernate.engine.spi.CollectionEntry.postFlush(CollectionEntry.java:214)
at
org.hibernate.event.internal.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:369)
at
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
at
org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)
at
org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
at
org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at
org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at
org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
at
org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at sun.reflect.GeneratedMethodAccessor191.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at
org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy349.commit(Unknown Source)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy304.save(Unknown Source)
at
org.springframework.data.repository.support.CrudRepositoryInvoker.invokeSave(CrudRepositoryInvoker.java:100)
at
org.springframework.data.rest.core.support.UnwrappingRepositoryInvokerFactory$UnwrappingRepositoryInvoker.invokeSave(UnwrappingRepositoryInvokerFactory.java:225)
at
org.springframework.data.querydsl.QuerydslRepositoryInvokerAdapter.invokeSave(QuerydslRepositoryInvokerAdapter.java:158)
at
org.springframework.data.rest.webmvc.RepositoryEntityController.createAndReturn(RepositoryEntityController.java:514)
at
org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(RepositoryEntityController.java:276)
at sun.reflect.GeneratedMethodAccessor325.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
at
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:261)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:115)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
at
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
com.nemesis.platform.core.filter.RestAuthenticationFilter.doFilterInternal(RestAuthenticationFilter.java:70)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
com.nemesis.platform.module.cms.storefront.filter.PathLocaleFilter.doFilterInternal(PathLocaleFilter.java:87)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:126)
at
org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
I'm writing here because the message says this might indicate a bug in
hibernate.
--
Regards, Petar!
Karlovo, Bulgaria.
---
Public PGP Key at:
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x19658550C3110611
Key Fingerprint: A369 A7EE 61BC 93A3 CDFF 55A5 1965 8550 C311 0611
9 years, 6 months
Follow on locking usability enhancement for Oracle
by Vlad Mihalcea
Hi,
After reviewing the PR for https://hibernate.atlassian.net/browse/HHH-9486,
I realized we could indeed improve the follow on locking for Oracle.
The issue with Oracle is partly explained in the Oracle docs:
https://docs.oracle.com/database/121/SQLRF/statements_10002.htm#sthref7465
The basic idea is that FOR UPDATE does not work with GROUP BY, DISTINCT,
and also nested selects which is what we use for pagination.
For those, the setMaxResults works, but not setFirstResult. Also, ORDER BY
causes some issues too.
This way, we could do something like this:
1. In Dialect, we deprecate useFollowOnLocking and add a new method to take
QueryParameters
@Deprecated
public boolean useFollowOnLocking() {
return useFollowOnLocking( null );
}
public boolean useFollowOnLocking(QueryParameters parameters) {
return false;
}
2. In Oracle82Dialect:
@Override
public boolean useFollowOnLocking(QueryParameters parameters) {
String lowerCaseSQL = parameters.getFilteredSQL().toLowerCase();
return parameters.hasRowSelection() && (
parameters.getRowSelection().getFirstRow() != null ||
lowerCaseSQL.contains( "distinct" ) ||
lowerCaseSQL.contains( "group by" ) ||
lowerCaseSQL.contains( "order by" )
);
}
3. We could also add a way for the user to override this behavior in
Dialect if he knows that the underlying statement works.
Although we include all those safety checks, we might miss some use case,
and this way the user can have a better control on the follow on locking
approach.
For this we could add a setFollowOnLocking on LockOptions.
List<Product> products = session.createQuery(
"select p from Product p order by p.id", Product.class )
.setLockOptions( new LockOptions( LockMode.PESSIMISTIC_WRITE
).setFollowOnLocking( true ) )
.setMaxResults( 10 )
.getResultList();
If the user specified an explicit setFollowOnLocking, then we ignore the
Dialect logic and just go with his option even if that means that he might
get an exception.
What do you think fo this?
Vlad
9 years, 6 months