-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 
Author Message
 Post subject: Bug in tools? Can't get column meta data from Sybase
PostPosted: Fri Aug 12, 2005 3:22 pm 
Newbie

Joined: Tue Aug 02, 2005 3:21 pm
Posts: 14
Hi,

The JDBCBinder class uses the DatabaseMetaData.getColumns() method, passing null as the last argument. When the corresponding Sybase stored proc is called, that null argument is received as an empty string - which causes problems.

I verified this behavior with both the Jconnect JDBC driver as well as jtds. I also wrote a short Java program that uses the same getColumns() method call, and it worked just fine.

So, the Hibernate tools are doing something strange that is causing this problem, so that I am unable to reverse engineer a Sybase database.

BTW, it is at line 732 where JDBCBinder makes the call to getColumns and immediately fails. I did also verify that the other arguments to the getColumns call are valid and correct by seeing their values as Sybase receives them and directly calling the stored proc using those values. I see nothing that I am doing wrong.

Could it be something to do with the dialect? I've tried SybaseDialect, SybaseAnywhereDialect, and Sybase11Dialect.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 13, 2005 4:26 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
the dialect does not control the reverse engineering process.

But you don't show me what you think the error is ?
Is there some code you think should be different ?

And in any case - sybase seems to have a hard time delivering metadata when not running with autocommit set to true (which is pretty stupid IMO)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 15, 2005 1:41 pm 
Newbie

Joined: Tue Aug 02, 2005 3:21 pm
Posts: 14
Max,

The only code is related to the reference I provided to JDBCBinder.java. I don't know where Hibernate Tools is initializing the JDBC driver - perhaps it's being configured in a strange way. Again, I can get meta data by writing my own Java program - but it fails through Hibernate Tools.

Here is the test program I wrote:
----------------------------------------------------------------------------------------
import java.sql.*;

public class TestJDBCDriver {

public static void main(String[] args) {

String url = "jdbc:jtds:sybase://scsefpsddb01:5001;user=eqprod1;password=deriv8tives";
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");

Connection conn = DriverManager.getConnection(url, "eqprod1", "deriv8tives");

DatabaseMetaData meta = conn.getMetaData();
ResultSet res = meta.getTables(null, null, "hts_sec_master", null);
while (res.next()) {
String tableName = res.getString("TABLE_NAME");
String schemaName = res.getString("TABLE_SCHEM");
String catalogName = res.getString("TABLE_CAT");

ResultSet cres = meta.getColumns(catalogName, schemaName, tableName, null);
while (cres.next()) {

int sqlType = cres.getInt("DATA_TYPE");
String sqlTypeName = cres.getString("TYPE_NAME");
String columnName = cres.getString("COLUMN_NAME");
String columnDefaultValue = cres.getString("COLUMN_DEF");
// if columnNoNulls or columnNullableUnknown assume "not nullable"
boolean isNullable = (DatabaseMetaData.columnNullable == cres.getInt("NULLABLE"));
int size = cres.getInt("COLUMN_SIZE");
int decimalDigits = cres.getInt("DECIMAL_DIGITS");

System.out.println("Column info:");
System.out.println("/tName: "+columnName);
}
}

} catch(Exception e) {
e.printStackTrace();
}
}
}
-------------------------------------------------------------------------------------
Here's my Hibernate configuration, hibernate.cfg.xml:
-------------------------------------------------------------------------------------
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="connection.url">jdbc:jtds:sybase://scsefpsddb01:5001;user=eqprod1;password=deriv8tives</property>
<property name="connection.username">eqprod1</property>
<property name="connection.password">deriv8tives</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Sybase11Dialect</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>
-------------------------------------------------------------------------------------


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 15, 2005 2:01 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
so the code is equal to what is in JDBCBinder - correct ?

You haven't shown the exception yet, that would be helpfull.

We don't do much in Hibernate except calling setAutoCommit and other basic stuff (doesnt affect other jdbc drivers)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 12:14 am 
Beginner
Beginner

Joined: Mon Nov 07, 2005 11:10 pm
Posts: 30
I am also having this problem.

The problem is that, when JConnect tries to get the columns of the tables, it calls the stored proc sp_jdbc_columns.

However, this stored proc internally creates a temporary table in tempdb ... which means that calling metadata will fail if you have started a transaction ( e.g. when autocommit is true ).

To simulate from the command-line even without Jdbc, do this:

1> begin tran
2> go
1> sp_jdbc_columns 'campaign', 'dbo', 'sgtest'
2> go
Msg 2762, Level 16, State 3:
Server 'SYBASE', Procedure 'sp_jdbc_columns', Line 107:
The 'CREATE TABLE' command is not allowed within a multi-statement transaction in the 'tempdb' database.
Msg 208, Level 16, State 6:
Server 'SYBASE', Procedure 'sp_jdbc_columns', Line 447:
#jdbc_columns not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
(return status = -6)

The above error is what you will see in Eclipse's error log ( if you have enabled it ) from Hibernate.


The only solution is to have autocommit set to false, and make sure that when retreiving metadata, the connection is not in a "middle" of a transaction.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 12:21 am 
Beginner
Beginner

Joined: Mon Nov 07, 2005 11:10 pm
Posts: 30
Error 2005-11-08 15:16:56.954 Problem while reading database schema
org.hibernate.exception.GenericJDBCException: Error while reading column meta data for sgtest.dbo.content_item_vers
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:91)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:79)
at org.hibernate.cfg.reveng.JDBCReader.processBasicColumns(JDBCReader.java:473)
at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:56)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter$1.execute(Unknown Source)
at org.hibernate.console.execution.DefaultExecutionContext.execute(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.readDatabaseSchema(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.getChildren(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.getChildren(Unknown Source)
at org.hibernate.eclipse.console.workbench.BasicWorkbenchAdapter.fetchDeferredChildren(Unknown Source)
at org.eclipse.ui.progress.DeferredTreeContentManager$1.run(DeferredTreeContentManager.java:192)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)
Caused by: com.sybase.jdbc2.jdbc.SybSQLException: The 'CREATE TABLE' command is not allowed within a multi-statement transaction in the 'tempdb' database.
at com.sybase.jdbc2.tds.Tds.processEed(Tds.java:2834)
at com.sybase.jdbc2.tds.Tds.nextResult(Tds.java:2156)
at com.sybase.jdbc2.jdbc.ResultGetter.nextResult(ResultGetter.java:69)
at com.sybase.jdbc2.jdbc.SybStatement.nextResult(SybStatement.java:220)
at com.sybase.jdbc2.jdbc.SybStatement.nextResult(SybStatement.java:203)
at com.sybase.jdbc2.jdbc.SybStatement.queryLoop(SybStatement.java:1596)
at com.sybase.jdbc2.jdbc.SybCallableStatement.executeQuery(SybCallableStatement.java:102)
at com.sybase.jdbc2.jdbc.SybDatabaseMetaData.returnResults(SybDatabaseMetaData.java:2379)
at com.sybase.jdbc2.jdbc.SybDatabaseMetaData.getColumns(SybDatabaseMetaData.java:1983)
at org.hibernate.cfg.reveng.JDBCReader.processBasicColumns(JDBCReader.java:418)
... 9 more

Looking at the other stored procs used for metadata, it seems that this problem is not limited to finding out the columns of a table, but other metadata as well.

( I just wonder why not simply retrieving from the sysxxx tables !!! )


Here are the details:

com.sybase.jdbc2.jdbc.SybSQLException: The 'CREATE TABLE' command is not allowed within a multi-statement transaction in the 'tempdb' database.
at com.sybase.jdbc2.tds.Tds.processEed(Tds.java:2834)
at com.sybase.jdbc2.tds.Tds.nextResult(Tds.java:2156)
at com.sybase.jdbc2.jdbc.ResultGetter.nextResult(ResultGetter.java:69)
at com.sybase.jdbc2.jdbc.SybStatement.nextResult(SybStatement.java:220)
at com.sybase.jdbc2.jdbc.SybStatement.nextResult(SybStatement.java:203)
at com.sybase.jdbc2.jdbc.SybStatement.queryLoop(SybStatement.java:1596)
at com.sybase.jdbc2.jdbc.SybCallableStatement.executeQuery(SybCallableStatement.java:102)
at com.sybase.jdbc2.jdbc.SybDatabaseMetaData.returnResults(SybDatabaseMetaData.java:2379)
at com.sybase.jdbc2.jdbc.SybDatabaseMetaData.getColumns(SybDatabaseMetaData.java:1983)
at org.hibernate.cfg.reveng.JDBCReader.processBasicColumns(JDBCReader.java:418)
at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:56)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter$1.execute(Unknown Source)
at org.hibernate.console.execution.DefaultExecutionContext.execute(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.readDatabaseSchema(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.getChildren(Unknown Source)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.getChildren(Unknown Source)
at org.hibernate.eclipse.console.workbench.BasicWorkbenchAdapter.fetchDeferredChildren(Unknown Source)
at org.eclipse.ui.progress.DeferredTreeContentManager$1.run(DeferredTreeContentManager.java:192)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 1:36 am 
Beginner
Beginner

Joined: Mon Nov 07, 2005 11:10 pm
Posts: 30
Okay ... I got passed the error.

Fortunately, I am also the DBA ( and System Administrator, etc... ).

The solution is to enable 'ddl in tran' in tempdb. Run the following as sa in ASE:

sp_dboption tempdb, 'ddl in tran', true
go

use tempdb
go

checkpoint
go

However, this setting will be lost if you restart ASE, since tempdb is recreated everytime during a restart.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 2:37 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Quote:
Looking at the other stored procs used for metadata, it seems that this problem is not limited to finding out the columns of a table, but other metadata as well.

( I just wonder why not simply retrieving from the sysxxx tables !!! )


Feel free to contribute a SybaseMetadataDialect.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 2:46 am 
Beginner
Beginner

Joined: Mon Nov 07, 2005 11:10 pm
Posts: 30
max wrote:
Quote:
Looking at the other stored procs used for metadata, it seems that this problem is not limited to finding out the columns of a table, but other metadata as well.

( I just wonder why not simply retrieving from the sysxxx tables !!! )


Feel free to contribute a SybaseMetadataDialect.



No need. As earlier stated, the solution was to:

sp_dboption tempdb, 'ddl in tran', true
go

use tempdb
go

checkpoint
go


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 6:38 pm 
Newbie

Joined: Thu Dec 01, 2005 5:55 pm
Posts: 2
I am also running into this error but the Sybase documentation states in a somewhat ambigous fashion to avoid doing this and you should never turn on this option. I am not the DBA so I do not have the luxury of altering the tempdb settings. I believe Sybase may have the answer so I will open a support ticket to try to find the answer.

From the Sybase 12.5 Transact SQL Guide
[Warning!

Be careful when using data definition commands. The only scenario in which using data definition language commands inside transactions is justified is in create schema. Data definition language commands hold locks on system tables such as sysobjects. If you use data definition language commands inside transactions, keep the transactions short.

Avoid using data definition language commands on tempdb within transactions; doing so can slow performance to a halt. Always leave ddl in tran set to false in tempdb.





jsalvo wrote:
Okay ... I got passed the error.

Fortunately, I am also the DBA ( and System Administrator, etc... ).

The solution is to enable 'ddl in tran' in tempdb. Run the following as sa in ASE:

sp_dboption tempdb, 'ddl in tran', true
go

use tempdb
go

checkpoint
go

However, this setting will be lost if you restart ASE, since tempdb is recreated everytime during a restart.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 6:49 pm 
Newbie

Joined: Thu Dec 01, 2005 5:55 pm
Posts: 2
One of my colleagues had already solved this. The solution, at least for us, is the add the following to your hibernate config file:

<property name="hibernate.connection.autocommit">true</property>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 6:53 pm 
Beginner
Beginner

Joined: Mon Nov 07, 2005 11:10 pm
Posts: 30
jridgway wrote:
One of my colleagues had already solved this. The solution, at least for us, is the add the following to your hibernate config file:

<property name="hibernate.connection.autocommit">true</property>



Do you really want autocommit to be true ??

How does this setting affect session.beginTransaction() and Transaction.commit() ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 1:48 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
guys please remember that the tools are NOT executing any DML operations while reverse engineering! What goes on is that sybase for some reason wants to create tables internally when I ask for which tables, columns etc. there is in the database....does not make (real) sense not being able to get metadata during a transaction.

So I see this as a sybase bug which can be worked around in two ways - one is to enable the flag in sybase and the other is to enable autocommit in the configuration you use with the hibernate tools when performing reverse engineering.

_________________
Max
Don't forget to rate


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.