[Hibernate-JIRA] Created: (HHH-4647) Problems with @JoinColumn referencedColumnName and quoted column and table names
by Peter Brant (JIRA)
Problems with @JoinColumn referencedColumnName and quoted column and table names
--------------------------------------------------------------------------------
Key: HHH-4647
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4647
Project: Hibernate Core
Issue Type: Bug
Components: annotations, core
Affects Versions: 3.5.0-Beta-2
Environment: current CVS, not database platform dependent
Reporter: Peter Brant
Attachments: hibernate-annotations.patch, hibernate-core.patch, test-case.zip
There are really two separate issues here, but the test case reduction and patches are so small (and involve related functionality) they are combined.
#1: A referencedColumnName that references a quoted target column cannot be found. The test case is app.TestReferencedColumnName#testQuotedReferencedColumnName(). The patch is hibernate-annotations.patch.
#2: An invalid referencedColumnName (including the unquoted version of a valid column) results in an infinite loop in o.h.c.Configuration$MappingsImpl#getPhysicalColumnName(). The test case is app.TestReferencedColumnName#testInvalidReferencedColumnNameOnQuotedTable. The patch is hibernate-core.patch. It looks like the same issue exists with getLogicalColumnName(), but I'm not sure where this is used (i.e. how to test it) so I left it alone.
--
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
14 years, 5 months
[Hibernate-JIRA] Created: (HHH-5109) @OneToOne - too many joins
by Marek Romanowski (JIRA)
@OneToOne - too many joins
--------------------------
Key: HHH-5109
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5109
Project: Hibernate Core
Issue Type: Bug
Components: annotations, core
Affects Versions: 3.5.0-Final
Reporter: Marek Romanowski
Attachments: hibernate-one-to-one.zip
With classes like this:
@Entity
@Proxy(lazy=false)
class Owner {
@javax.persistence.Id
@javax.persistence.Column(name = "ID", columnDefinition = "BIGINT")
public java.lang.Long getId() {
return this.id;
}
public void setId(java.lang.Long newValue) {
this.id = newValue;
}
private java.lang.Long id;
@javax.persistence.OneToOne(targetEntity = Owned.class)
@org.hibernate.annotations.Cascade( { org.hibernate.annotations.CascadeType.ALL })
@javax.persistence.PrimaryKeyJoinColumn
public Owned getOwned() {
return this.owned;
}
public void setOwned(Owned owned) {
this.owned = owned;
if (owned != null) {
owned.setOwner(this);
}
}
private Owned owned;
}
@Entity
@Proxy(lazy=false)
class Owned {
private java.lang.Long id;
@javax.persistence.Id
@javax.persistence.GeneratedValue(generator = "foreign")
@org.hibernate.annotations.GenericGenerator(
name = "foreign",
strategy = "foreign",
parameters = { @org.hibernate.annotations.Parameter(name = "property", value = "owner") })
@javax.persistence.Column(name = "ID", columnDefinition = "BIGINT")
public java.lang.Long getId() {
return this.id;
}
public void setId(java.lang.Long newValue) {
this.id = newValue;
}
@javax.persistence.OneToOne(targetEntity = Owner.class, mappedBy = "owned")
@javax.persistence.PrimaryKeyJoinColumn
public Owner getOwner() {
return this.owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
private Owner owner;
}
Idea is to have one to one relation between Owner and Owned mapped by "id" properties in both entities. So for each pair owner.id == owned.id.
code:
session.load(Owner.class, 1L)
turns into SQL:
select owner0_.ID as ID0_2_, owned1_.ID as ID1_0_, owner2_.ID as ID0_1_
from Owner owner0_ left outer
join Owned owned1_ on owner0_.ID=owned1_.ID
left outer join Owner owner2_ on owned1_.ID=owner2_.ID
where owner0_.ID=?
Isn't it wrong? @OneToOne annotation on getOwner() has mappedBy="owned" property, so I would expect this code to generate SQL with only one join (only "owner join owned"). If this is correct H3 behaviour in this case, then write what should I change in annotations to get described behaviour, please.
I've attached maven project with one test encapsulating this issue.
--
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
14 years, 5 months
[Hibernate-JIRA] Created: (HHH-3909) Improve Performance of FieldInterceptionHandler (and thus of flushing)
by Ovidio Mallo (JIRA)
Improve Performance of FieldInterceptionHandler (and thus of flushing)
----------------------------------------------------------------------
Key: HHH-3909
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3909
Project: Hibernate Core
Issue Type: Improvement
Components: core
Affects Versions: 3.3.1
Reporter: Ovidio Mallo
Attachments: patch.txt
In the FieldInterceptionHelper class, the method Class#getInterfaces() is used in conjunction with a subsequent loop over all interfaces of an entity class in order to check whether a bytecode instrumentation interface of CGlib or Javassist is found. This is done that way since CGlib and Javassist are both optional so they should only be accessed at runtime if available on the classpath. Attached you can find a simple patch which only once checks whether CGlib and/or Javassist is available and then uses the more performant "instanceof" operator in order to check whether an entity has an interceptor. The new code still guarantees that no CGlib or Javassist class is accessed if it is not on the classpath.
The patch helps making the FieldInterceptionHelper methods more performant which can e.g. be noticed during a session flush, especially if bytecode instrumentation is used. In order to measure the performance impact of the patch I've written a simple program which does the following:
1. insert 100 thousand entities into a simple table with 6 numeric attributes
2. do an initial flush on the session in order to execute all the insert statements
3. loop 300 times and do a flush on the session (only a dirty check is performed, no database operation)
I've time the flushes under point 3 above with and without bytecode instrumentation for the used entity. Here are the results:
USING BYTECODE INSTRUMENTATION
=============================
* SUN JVM 1.6.0_05:
- without patch: 25734ms
- with patch: 11015ms
* IBM JVM 1.4.2:
- without patch: 20672ms
- with patch: 11140ms
WITHOUT BYTECODE INSTRUMENTATION
================================
* SUN JVM 1.6.0_05:
- without patch: 73328ms
- with patch: 62015ms
* IBM JVM 1.4.2:
- without patch: 70344ms
- with patch: 61125ms
Using bytecode instrumentation, the performance improvement is about of a factor of 2-2.5. When not using bytecode instrumentation, the overall impact is of course less relevant since the rest of the work done during flush is more expensive anyway. In any case, IMHO the impact when using bytecode instrumentation is relevant.
The patch is very simple and only touches the FieldInterceptionHelper class.
--
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
14 years, 5 months
[Hibernate-JIRA] Created: (HHH-5185) Columns in Formulas not always rewritten, triggers ambiguous column SQL error
by Chris Wilson (JIRA)
Columns in Formulas not always rewritten, triggers ambiguous column SQL error
-----------------------------------------------------------------------------
Key: HHH-5185
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5185
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.5.1
Environment: MySQL Server version: 5.0.51a-3ubuntu5.5 (Ubuntu)
Hibernate version 3.5.1-Final
Reporter: Chris Wilson
Attachments: HibernateJoinFormulaAliasTest.java
The attached test case joins an entity with two @Formulas twice. The first @Formula is the algebraic expression "(kittens * 4) + 3", the second is a SQL function "EXTRACT(MONTH FROM birthday)".
kittens is rewritten but birthday is not. Because the table is joined twice, MySQL reports the error:
{code}
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'birthday' in field list is ambiguous
{code}
which shows up as:
{code}
org.hibernate.exception.ConstraintViolationException: could not load an entity: [org.aptivate.hibernate.test.HibernateJoinFormulaAliasTest$House#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1937)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3270)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:403)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:155)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1065)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1056)
at org.aptivate.hibernate.test.HibernateJoinFormulaAliasTest.testFailing(HibernateJoinFormulaAliasTest.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.aptivate.hibernate.test.base.HibernateTestBase.runTestMethod(HibernateTestBase.java:204)
at org.aptivate.hibernate.test.base.HibernateTestBase.runTest(HibernateTestBase.java:117)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'birthday' in field list is ambiguous
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3562)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3494)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1960)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2114)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2696)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2105)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2264)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1849)
at org.hibernate.loader.Loader.doQuery(Loader.java:718)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1933)
... 31 more
{code}
The rewritten SQL is:
{code}
select
hibernatej0_.id as id0_2_,
cats1x1_.firstHome_id as firstHome4_0_4_,
cats1x1_.id as id4_,
cats1x1_.id as id1_0_,
cats1x1_.birthday as birthday1_0_,
cats1x1_.firstHome_id as firstHome4_1_0_,
cats1x1_.kittens as kittens1_0_,
cats1x1_.secondHome_id as secondHome5_1_0_,
EXTRACT(MONTH
FROM
birthday) as formula0_0_,
(cats1x1_.kittens * 4) + 3 as formula1_0_,
cats2x2_.secondHome_id as secondHome5_0_5_,
cats2x2_.id as id5_,
cats2x2_.id as id1_1_,
cats2x2_.birthday as birthday1_1_,
cats2x2_.firstHome_id as firstHome4_1_1_,
cats2x2_.kittens as kittens1_1_,
cats2x2_.secondHome_id as secondHome5_1_1_,
EXTRACT(MONTH
FROM
birthday) as formula0_1_,
(cats2x2_.kittens * 4) + 3 as formula1_1_
from
houses hibernatej0_
left outer join
cats cats1x1_
on hibernatej0_.id=cats1x1_.firstHome_id
left outer join
cats cats2x2_
on hibernatej0_.id=cats2x2_.secondHome_id
where
hibernatej0_.id=?
{code}
There's no apparent workaround that lets us reference the same column in a formula in a table that's joined twice.
--
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
14 years, 6 months
[Hibernate-JIRA] Created: (HHH-2339) merge instumented class fails
by Alexey Romanchuk (JIRA)
merge instumented class fails
-----------------------------
Key: HHH-2339
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2339
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1, 3.2.0.ga
Environment: Hibernate 3.2.1 (tested with 3.2.0 too)
Postgresql 8.1.4
Reporter: Alexey Romanchuk
Priority: Blocker
When we try to merge instrumented detached entity with lazy no-proxy many-to-one association we have org.hibernate.LazyInitializationException.
It occurs because cascade try to process all associations in Cascade class, but object disconected from session and can not obtaion lazy property.
If classes are not instrumented all works ok.
Why merge action does not have overrided performOnLazyProperty mathod to prevent fetching lazy properties?
Here it is small example that illustates problem.
===MAPPING===
<hibernate-mapping>
<class name="Client" table="test_client">
<id name="id" column="id" type="long">
<generator class="sequence">
<param name="sequence">test_seq</param>
</generator>
</id>
<property name="name" column="name"/>
<many-to-one name="info" class="LoginInfo" lazy="no-proxy" column="info_id" cascade="merge,evict"/>
</class>
<class name="LoginInfo" table="test_login_info">
<id name="id" column="id" type="long">
<generator class="sequence">
<param name="sequence">test_seq</param>
</generator>
</id>
<property name="login" column="login"/>
<property name="pass" column="pass"/>
</class>
</hibernate-mapping>
===JAVA===
===DOMAIN===
public class Client
{
private long id;
private String name;
private LoginInfo info;
//getters and setters
}
public class LoginInfo
{
private long id;
private String login;
private String pass;
//getters and setters
}
===USAGE===
public class Main
{
public static void main( String[] args )
{
Session s1 = sf.openSession();
s1.beginTransaction();
Client c = ( Client ) s1.get( Client.class, 2l );
s1.flush();
s1.getTransaction().commit();
s1.close();
Session s2 = sf.openSession();
s2.beginTransaction();
c = ( Client ) s2.merge( c );
s2.flush();
s2.getTransaction().commit();
s2.close();
}
}
==STACKTRACE===
org.hibernate.LazyInitializationException: session is not connected
at org.hibernate.intercept.AbstractFieldInterceptor.intercept(AbstractFieldInterceptor.java:67)
at org.hibernate.intercept.cglib.FieldInterceptorImpl.readObject(FieldInterceptorImpl.java:75)
at Client.$cglib_read_info(Client.java)
at Client.getInfo(Client.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:277)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:3529)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:407)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:266)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at Main.main(Main.java:56)
--
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
14 years, 6 months
[Hibernate-JIRA] Created: (HHH-2388) Insert w/ identity column fails on Sybase but no exception occurs
by Tim Morrow (JIRA)
Insert w/ identity column fails on Sybase but no exception occurs
-----------------------------------------------------------------
Key: HHH-2388
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2388
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1
Environment: Hibernate 3.2.1.GA with annotations
Sybase jConnect 6.05 JDBC driver
Sybase ASE 15 database
Reporter: Tim Morrow
I have a scenario where storing a new entity fails (i.e. the row is not inserted) but Hibernate does not realize this. No exceptions are thrown. Later, this leads to AssertionFailures (if two such entities fail in the same session - they both have the same PK).
The problem specifically occurs with a table that has a numeric column with precision (e.g. numeric(10,4)) and an identity column when using Sybase ASE.
==========
To reproduce:
1. Use Sybase jConnect 6.05 JDBC driver with Sybase ASE 15 database.
2. Define an Entity with a long ID and BigDecimal numeric column.
3. Create a corresponding table with an identity column and numeric(10, 4) column.
For example:
hibernate.MyEntity.java:
-----------------------------------------
package hibernate;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;
@Entity
@Table(name = "z_tim_test")
public class MyEntity {
private BigDecimal cost;
private long id;
public MyEntity() {}
@Column(columnDefinition = "numeric(10,4)")
@NotNull public final BigDecimal getCost() {
return cost;
}
@GeneratedValue(strategy = GenerationType.AUTO)
@Id public final long getId() {
return id;
}
public final void setCost(BigDecimal cost) {
this.cost = cost;
}
public final void setId(long id) {
this.id = id;
}
}
Table:
-----------------------------------------
CREATE TABLE z_tim_test
(
id numeric(19) PRIMARY KEY not null,
cost numeric(10,4) not null
);
4. Write some code that stores a new entity and tries to load it:
MyEntity myEntity = new MyEntity();
myEntity.setCost(new BigDecimal("123.12345"));
session.save(myEntity);
session.flush();
session.clear();
List<MyEntity> results = session.createCriteria(MyEntity.class).list();
if (results.size() != 1) {
throw new IllegalStateException("Expected 1 result");
}
This test will throw the IllegalStateException because the row was not persisted and no errors occurred.
Reason:
* Sybase does not thrown any SQLException when you try and persist a numeric value whose scale exceeds that defined on the column. Instead, it returns an updateCount of zero and an identity column value of zero.
* Hibernate does not check the updateCount after executing the statement when using an Identity column. The offending code is in:
org.hibernate.id.IdentityGenerator$InsertSelectDelegate
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
if ( !insert.execute() ) {
while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
// do nothing until we hit the rsult set containing the generated id
}
}
ResultSet rs = insert.getResultSet();
try {
return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
}
finally {
rs.close();
}
}
It ignores the updateCount.
The net result is that the object is assigned a PK value of zero. Hibernate continues. My applicaiton is unaware that the row failed to insert.
Solution:
It would seem to me replacing the above code with:
if (!insert.execute()) {
if (insert.getUpdateCount() < 1) {
throw new HibernateException("No update occurred");
}
while (!insert.getMoreResults()) {
// do nothing until we hit the rsult set containing the generated id
}
}
Would take care of the problem?
--
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
14 years, 6 months