[Hibernate-JIRA] Created: (HHH-6581) JPA 2.0 Spec. Violation with Access and MappedSuperclass
by Laird Nelson (JIRA)
JPA 2.0 Spec. Violation with Access and MappedSuperclass
--------------------------------------------------------
Key: HHH-6581
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6581
Project: Hibernate Core
Issue Type: Bug
Components: annotations, core
Affects Versions: 3.6.6
Reporter: Laird Nelson
Once I create this issue and get the bug number I will be creating a test case.
The bug is fully described in the Hibernate user forums: https://forum.hibernate.org/viewtopic.php?f=1&t=1012254
Suppose I have a {{@MappedSuperclass}} like this:
{code:title=A.java}
@Access(AccessType.FIELD)
@MappedSuperclass
public class A {
private long id;
@Column(name = "some_other_field")
private String someOtherField;
@Access(AccessType.PROPERTY)
@Column(name = "id")
@GeneratedValue
@Id
public long getId() {
return this.id;
}
protected void setId(final long id) {
this.id = id;
}
}
{code}
Then suppose I extend it with a (minimally-annotated) entity:
{code:title=B.java}
@Entity
@Table(name = "b")
public class B extends A {
@Column(name = "long_description")
private String longDescription;
// various other persistent fields here
public String getLongDescription() {
return this.longDescription;
}
public void setLongDescription(final String description) {
this.longDescription = description;
}
}
{code}
Hibernate 3.6.6.Final logs exceptions indicating that it cannot find the {{LONGDESCRIPTION}} column for this entity. This implies that somehow {{AccessType.PROPERTY}} has been used on the longDescription attribute, where {{AccessType.FIELD}} should have been used instead. This is a violation of the spec.
It's almost like the mere fact that {{AccessType.PROPERTY}} was used in the {{@MappedSuperclass}} at all caused it to be "latched" as the default for the rest of the entity hierarchy, which is clearly not what should happen.
Section 2.3.2 in the JPA 2.0 specification reads as follows:
bq. An access type for an individual entity class, mapped superclass, or embeddable class can be specified for that class independent of the default for the entity hierarchy by means of the Access annotation applied to the class. This explicit access type specification does not affect the access type of other entity classes or mapped superclasses in the entity hierarchy.
Then it also says, later:
bq. Persistent state inherited from superclasses is accessed in accordance with the access types of those superclasses.
My interpretation of all this is that I shouldn't have to put the {{@Access}} annotation on the {{@Entity}} in my example above. {{B.java}} should inherit the fact that the "{{id}}" property has {{AccessType.PROPERTY}}, and, by virtue of the default algorithm specified in section 3.2.1, should apply {{AccessType.FIELD}} to all other elements of its persistent state.
Guy Pelletier from EclipseLink, upon having this all explained to him, says:
bq. The behavior you describe is indeed intentionally implemented that way [i.e. no extra @Access annotation on B.java required] in EclipseLink as this is also our interpretation of the spec as well (and we confirmed with direct discussions with members of the spec committee beforehand).
I'll put a test case together shortly.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 8 months
[Hibernate-JIRA] Created: (HHH-6644) JTA CacheSynchronization can cause exceptions with stateless sessions
by Andrew Flegg (JIRA)
JTA CacheSynchronization can cause exceptions with stateless sessions
---------------------------------------------------------------------
Key: HHH-6644
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6644
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.5.6
Environment: Hibernate Core 3.5.6, Oracle v10.2.0.3.0, JDBC driver v11.2.0.2.0, WebSphere Application Server 7.0.0.13
Reporter: Andrew Flegg
h2. 1. Background
In a JTA environment (using an XA data source), {{JDBCContext}} registers {{CacheSynchronization}} objects for running before & after transaction completion.
If a stateless session is opened _within_ an existing session and using the same connection, a {{CacheSynchronization}} will be registered against the {{StatelessSessionImpl}}. However, {{org.hibernate.transaction.CacheSynchronization.beforeCompletion()}} is called when the transaction ends; not when the stateless session ends.
In pseudo-code this might look like, using Spring's {{@Transactional}} aspect:
{code:java}
@Transactional
public void test() {
Session session = sessionFactory.getCurrentSession();
session.createQuery("from People").list();
StatelessSession statelessSession = sessionFactory.openStatelessSession(session.connection());
statelessSession.createQuery("from Dogs").list();
statelessSession.close();
session.createQuery("from People").list();
}
{code}
{{org.hibernate.impl.StatelessSessionImpl.managedFlush()}} will error if the session has been closed. [{{CacheSynchronization.beforeCompletion()}}|https://github.com/hibernate/hibernate-core/blob/3.5/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java#L68] will call {{managedFlush()}} if:
* {{StatelessSessionImpl.isFlushModeNever()}} is false.
* _and_ {{StatelessSessionImpl.isFlushBeforeCompletionEnabled()}} is true
* _and_ the transaction isn't rollback-only.
As expected, {{StatelessSessionImpl}} has hardcoded _false_ and _true_ for {{isFlushModeNever()}} and {{isFlushBeforeCompletionEnabled()}}, respectively.
The above pseudo-code will therefore fail when the transaction is committed. The top of the stack-trace is:
{noformat}
Exception caught from before_completion synchronization operation: org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.StatelessSessionImpl.managedFlush(StatelessSessionImpl.java:332)
at org.hibernate.transaction.CacheSynchronization.beforeCompletion(CacheSynchronization.java:88)
at com.ibm.tx.jta.RegisteredSyncs.coreDistributeBefore(RegisteredSyncs.java:289)
at com.ibm.ws.tx.jta.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:150)
at com.ibm.ws.tx.jta.TransactionImpl.prePrepare(TransactionImpl.java:2316)
at com.ibm.ws.tx.jta.TransactionImpl.stage1CommitProcessing(TransactionImpl.java:536)
at com.ibm.tx.jta.TransactionImpl.processCommit(TransactionImpl.java:983)
at com.ibm.tx.jta.TransactionImpl.commit(TransactionImpl.java:918)
{noformat}
Looking at github, this still affects [{{CacheSynchronization}} in Hibernate 3.6|https://github.com/hibernate/hibernate-core/blob/3.6/hibernate-core/s...].
h2. 2. Proposed fix
The proposed fix is to make {{CacheSynchronization}} check {{TransactionFactory.Context#isClosed()}}.
*From:*
{code:java}
flush = !ctx.isFlushModeNever() &&
ctx.isFlushBeforeCompletionEnabled() &&
!JTAHelper.isRollback( transaction.getStatus() );
//actually, this last test is probably unnecessary, since
//beforeCompletion() doesn't get called during rollback
{code}
*To:*
{code:java}
flush = !ctx.isFlushModeNever() &&
ctx.isFlushBeforeCompletionEnabled() &&
!ctx.isClosed() &&
!JTAHelper.isRollback( transaction.getStatus() );
//actually, this last test is probably unnecessary, since
//beforeCompletion() doesn't get called during rollback
{code}
h3. 2.1. Mockito-based test
{code:java}
/**
* Check the behaviour of {@link CacheSynchronization} when the session has
* been closed.
*
* @throws SystemException if something goes wrong
*/
public void testCacheSynchronisation() throws SystemException {
final TransactionFactory.Context ctx = mock(TransactionFactory.Context.class);
doThrow(new SessionException("Session is closed!")).when(ctx).managedFlush();
when(ctx.isClosed()).thenReturn(true);
when(ctx.isFlushModeNever()).thenReturn(false);
when(ctx.isFlushBeforeCompletionEnabled()).thenReturn(true);
final javax.transaction.Transaction transaction = mock(javax.transaction.Transaction.class);
when(transaction.getStatus()).thenReturn(0);
final org.hibernate.Transaction tx = mock(org.hibernate.Transaction.class);
final JDBCContext jdbcContext = mock(JDBCContext.class);
new CacheSynchronization(ctx, jdbcContext, transaction, tx).beforeCompletion();
verify(jdbcContext).beforeTransactionCompletion(tx);
}
{code}
h3. 2.2. Alternatives
{{StatelessSessionImpl.isFlushBeforeCompletionEnabled()}} could return a boolean based on whether or not it was closed, rather than {{CacheSynchronization}} checking for closedness itself.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 8 months
[Hibernate-JIRA] Created: (HSEARCH-901) ClassCastException during creation of index: Hibernate (Search) assumes varchar entity field called "id" is an Integer but it isn't
by Jan Snelders (JIRA)
ClassCastException during creation of index: Hibernate (Search) assumes varchar entity field called "id" is an Integer but it isn't
-----------------------------------------------------------------------------------------------------------------------------------
Key: HSEARCH-901
URL: http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-901
Project: Hibernate Search
Issue Type: Bug
Components: massindexer
Affects Versions: 3.4.1.Final
Environment: Windows 7, Java 6.27 (x64), JBoss 6.1 using JPA2, Hibernate 3.6.6.Final, Lucene 3.1.0, MySQL driver 5.1.17, MySQL 5.1.47 (on linux CentOS 5.6 - 2.6.18-238.19.1.el5)
Reporter: Jan Snelders
Attachments: files.zip
I run into a ClassCastException(Integer cannot be cast to String) which I found out was related to one varchar field in one of my entities (Tests.java).
For some reason hibernate assumes and treats this field as an integer and later runs into the reported ClassCastException. This only happens if the field is named "id" fully lowercase. Renaming this to "ID" solves the problem.
This all happens while trying to create new Lucene indexes (fullTextEntityManager.createIndexer().startAndWait();) for Hibernate Search for my JPA2 entities using Hibernate as JPA2 provider.
How to reproduce:
Load the TestsTable.sql in your MySQL db (see attached zip)
Set up the datasource in JBoss 6.1. (my datasource in excel file)
Deploy a JPA project using the Tests table to the JBoss server (see persistence.xml and Tests.java)
Try creating the indexes through JPA like
...
@PersistenceContext(name="HeliumJPA")
private EntityManager em;
public void createSearchIndex(){
try {
System.out.println("Start Lucene Indexing");
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
fullTextEntityManager.createIndexer().startAndWait();
System.out.println("Lucene Indexing finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
You will get the ClassCastException:
16:40:46,872 ERROR [org.hibernate.search.batchindexing.IdentifierConsumerEntityProducer] error during batch indexing: : java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at org.hibernate.type.descriptor.java.StringTypeDescriptor.unwrap(StringTypeDescriptor.java:40) [:3.6.6.Final]
at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:52) [:3.6.6.Final]
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:91) [:3.6.6.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:283) [:3.6.6.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:278) [:3.6.6.Final]
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1873) [:3.6.6.Final]
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1844) [:3.6.6.Final]
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1716) [:3.6.6.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:801) [:3.6.6.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) [:3.6.6.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2533) [:3.6.6.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) [:3.6.6.Final]
at org.hibernate.loader.Loader.list(Loader.java:2271) [:3.6.6.Final]
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119) [:3.6.6.Final]
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716) [:3.6.6.Final]
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347) [:3.6.6.Final]
at org.hibernate.search.batchindexing.IdentifierConsumerEntityProducer.loadList(IdentifierConsumerEntityProducer.java:141) [:3.4.1.Final]
at org.hibernate.search.batchindexing.IdentifierConsumerEntityProducer.loadAllFromQueue(IdentifierConsumerEntityProducer.java:110) [:3.4.1.Final]
at org.hibernate.search.batchindexing.IdentifierConsumerEntityProducer.run(IdentifierConsumerEntityProducer.java:87) [:3.4.1.Final]
at org.hibernate.search.batchindexing.OptionallyWrapInJTATransaction.run(OptionallyWrapInJTATransaction.java:78) [:3.4.1.Final]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) [:1.6.0_27]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [:1.6.0_27]
at java.lang.Thread.run(Unknown Source) [:1.6.0_27]
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 8 months
[Hibernate-JIRA] Created: (HHH-6123) Patch to support Oracle Hints in Hibernate queries
by Tad Smith (JIRA)
Patch to support Oracle Hints in Hibernate queries
--------------------------------------------------
Key: HHH-6123
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6123
Project: Hibernate Core
Issue Type: Patch
Components: core
Affects Versions: 3.6.2
Reporter: Tad Smith
Attachments: hibernate-oracle-hints-patch.zip
Supporting Oracle hints in Hibernate is a feature often requested by Hibernate users, though I'll admit should be used very rarely in practice. Actually, I had a manager that demanded it if we were to continue using Hibernate (He was new to the project with a C++/DBA background.), so I modified Hibernate to support it. I did this originally 2 years ago against Hibernate version 3.3.1. I've just updated it to support Hibernate version 3.6.2.
It would be great if this could be included in the Hibernate baseline. It's a relatively minor change and the design follows existing Hibernate patterns.
Thanks,
Tad
General Design:
========================
I modeled the implementation after the org.hibernate.dialect.Dialect.getLimitString() method. I added a new method to the org.hibernate.dialect.Dialect class called getQueryHintString(). I also modified the org.hibernate.Criteria and org.hibernate.Query interfaces to add a new method called setQueryHint(). This means you can create a Query from an HQL string and then apply the Oracle hint.
Other Dialect class implementation would easy override the getQueryHintString() method to support hints for other databases.
What's included in the patch:
===============================
I've included the 9 classes that were modified to support Oracle hints. I've also included a Maven POM file that should be able to generate the patch jar automatically and upload it to your Maven Repository. Just change the artifactId from "hibernate-core" to "hibernate-core--OracleHintsPatch". (I'm relatively new to Maven and this has not received much testing, so feel free to improve upon it.)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 8 months
[Hibernate-JIRA] Created: (HHH-6637) LOB test case failures with Teradata against Hibernate 3.6.
by David Repshas (JIRA)
LOB test case failures with Teradata against Hibernate 3.6.
-----------------------------------------------------------
Key: HHH-6637
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6637
Project: Hibernate Core
Issue Type: Bug
Components: testsuite
Affects Versions: 3.6.6
Environment: Hibernate 3.6.6 testsuite running against Teradata 13.10 DBS.
Reporter: David Repshas
The following two test cases fail when run against Teradata:
org.hibernate.test.lob.BlobLocatorTest.java
org.hibernate.test.lob.ClobLocatorTest.java
The error returned is:
Testcase: testBoundedBlobLocatorAccess(org.hibernate.test.lob.BlobLocatorTest): Caused an ERROR
[Teradata Database] [TeraJDBC 13.10.00.20] [Error 5766] [SQLState HY000] The Locator is invalid because the response spool has been
dropped.
com.teradata.jdbc.jdbc_4.util.JDBCException: [Teradata Database] [TeraJDBC 13.10.00.20] [Error 5766] [SQLState HY000] The Locator is
invalid because the response spool has been dropped.
The reason for the failure is that the Teradata Response Spool that returned the Locator must remain open while retrieving the data associated with the lob locator. From a JDBC perspective, this requires the Connection, Statement and ResultSet used to obtain the locator reamin open until the LOB data is extracted.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 8 months