-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: seam-gen mysql issues
PostPosted: Mon Jan 08, 2007 4:14 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
From: http://jira.jboss.com/jira/browse/JBSEAM-637

Quote:
To summarize, these three problems impacted my out-of-box experience with Seam:
* tables without primary keys (dummy composite key is generated and generator does not work with these)


Do you have a better suggestion ? An ORM need somehow to identify each row and if there is no primary key it has to be all the columns.

In hibernate tools (but not seam-gen yet) we support customizing this in reveng.xml and we should add additional support by choosing a unique constraint as the fallback primary key if there is one unique constraint.

Until then how about defining a primary key for your tables ? :)

Quote:
* no support for My SQL enum type


What would be needed to support it ?

And is the customizability supported via a custom reveng strategy enough ?

Quote:
* while trying to make it work, table drops were not reflected in generated project - several steps needed to remove dropped table


This is a tricky question since we somehow would need to keep track of what we have generated against before....and also (in future) be able to distinguish between a generation that only is done for a few tables and not all tables.

Do you know of any seam-gen-like tools that supports this "transparently" ? How do they work ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: Re: seam-gen mysql issues
PostPosted: Mon Jan 08, 2007 5:53 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
While reading my answers, please have in mind these things:
  • I tried Seam on existing project, thus I can't change database structure
  • I didn't put emphasis on best practices, but rather on out-of-box experience
  • Generated application may be incomplete, but it should work

max wrote:
From: http://jira.jboss.com/jira/browse/JBSEAM-637

Quote:
To summarize, these three problems impacted my out-of-box experience with Seam:
* tables without primary keys (dummy composite key is generated and generator does not work with these)


Do you have a better suggestion ? An ORM need somehow to identify each row and if there is no primary key it has to be all the columns.

In hibernate tools (but not seam-gen yet) we support customizing this in reveng.xml and we should add additional support by choosing a unique constraint as the fallback primary key if there is one unique constraint.

Until then how about defining a primary key for your tables ? :)


Tables without primary keys cause tools to create composite keys, which cause Seam to fail later because it can't work with composite keys. Generated application should work. Tables that cannot be processes correctly should be skipped or some dummy implementation that will at least allow other tables to work should be provided.
Quote:

Quote:
* no support for My SQL enum type


What would be needed to support it ?

And is the customizability supported via a custom reveng strategy enough ?


I'll try to do this with reveng.

For full support, tools should
  • detect enum columns
  • map them as enumeration
  • during entity creation, create enums, too
Simpler solution is to just map them to strings.
Quote:

Quote:
* while trying to make it work, table drops were not reflected in generated project - several steps needed to remove dropped table


This is a tricky question since we somehow would need to keep track of what we have generated against before....and also (in future) be able to distinguish between a generation that only is done for a few tables and not all tables.

Do you know of any seam-gen-like tools that supports this "transparently" ? How do they work ?


If previous two points are solved, this is not big issue anymore. I removed some tables because they didn't work. If generator can create correct application such occasions should be rare.

generate-entities could simply
  • take previous schema
  • delete classes that represent tables that doesn't exist anymore
  • store schema for next generation


Top
 Profile  
 
 Post subject: Re: seam-gen mysql issues
PostPosted: Mon Jan 08, 2007 8:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
max wrote:
From: http://jira.jboss.com/jira/browse/JBSEAM-637

Quote:
To summarize, these three problems impacted my out-of-box experience with Seam:
* tables without primary keys (dummy composite key is generated and generator does not work with these)


Do you have a better suggestion ? An ORM need somehow to identify each row and if there is no primary key it has to be all the columns.

In hibernate tools (but not seam-gen yet) we support customizing this in reveng.xml and we should add additional support by choosing a unique constraint as the fallback primary key if there is one unique constraint.

Until then how about defining a primary key for your tables ? :)


Tables without primary keys cause tools to create composite keys, which cause Seam to fail later because it can't work with composite keys. Generated application should work. Tables that cannot be processes correctly should be skipped or some dummy implementation that will at least allow other tables to work should be provided.
Quote:


Problematic since hibernate tools (and hibernate) at least work with these; but seam-gen doesn't. Hopefully seam-gen will support composite keys soon.

One comment is though that it is hard to handle *all* combinations of "broken" schemas (e.g. tables without clear identification of rows)
[/quote]

Quote:
* no support for My SQL enum type


What would be needed to support it ?

And is the customizability supported via a custom reveng strategy enough ?

[/quote]
I'll try to do this with reveng.

For full support, tools should

[*]detect enum columns
[/quote]

so it shold be mapped to an enum type, possible via reveng....

Quote:
[*]map them as enumeration


how do you know which enum it should map to ? e.g. what are the possible values ?

[*]during entity creation, create enums, too

same as above....sounds like something very db specific.

Quote:
Simpler solution is to just map them to strings.
Quote:
[/qupte]

what does it map to today ?

Quote:
Quote:
* while trying to make it work, table drops were not reflected in generated project - several steps needed to remove dropped table


This is a tricky question since we somehow would need to keep track of what we have generated against before....and also (in future) be able to distinguish between a generation that only is done for a few tables and not all tables.

Do you know of any seam-gen-like tools that supports this "transparently" ? How do they work ?


If previous two points are solved, this is not big issue anymore. I removed some tables because they didn't work. If generator can create correct application such occasions should be rare.

generate-entities could simply
  • take previous schema
  • delete classes that represent tables that doesn't exist anymore
  • store schema for next generation



does not cover all cases though...there is also unused enum's, id's, view's etc. including custom generations which is not trivial/safe to just delete.

It can be done to some extent but not optimal/perfect.

Again my question is if this is something you have seen somewhere else ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: Enum handling
PostPosted: Tue Jan 09, 2007 5:01 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
I did some more analysis. Problem could be solved in a very simple way, by forgetting enums completely.

First problem: char handling

Real problem is that MySql reports those fields as simple char, and Hibernate expects varchars for strings. Char handling should be fixed and this problem will not appear anymore.

I tried to do that in reveng, but without success. However, I managed to solve it using UserType.

Second problem: seam-gen, JPA and user types

Changes in reveng were not reflected fully in generated files, which caused same error again. Type of the property field was changes correctly (I was playing with Booleans), but user type was not put anywhere.

I solved this by mixing Hibernate annotations (@TypeDefs) with existing JPA annotations, but this looks ugly. This JPA stuff is a bit new to me so:
  • Is is possible to mix Hibernate annotations and configuration files with JPAs
  • Can reveng do that for me?


Top
 Profile  
 
 Post subject: Schema synchronization
PostPosted: Tue Jan 09, 2007 5:05 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
I saw some tools that can synchronize database structure between different versions of application, but I can't remember where. If I find something, I will post it here.


Top
 Profile  
 
 Post subject: Re: Enum handling
PostPosted: Tue Jan 09, 2007 5:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
zeljko_t wrote:
I did some more analysis. Problem could be solved in a very simple way, by forgetting enums completely.


...sorry, but could you be a tad more specific about those issues you list ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 7:06 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
First problem: char handling

In simplest solution, enums don't have to be treated as enums at all, because MySQL JDBC driver reports them as simple java.sql.Types CHAR field. Here is printout of my test application (ResultSetMetaData from simple select statement):

Code:
rsmd.getColumnClassName  :java.lang.String
rsmd.getColumnDisplaySize:1
rsmd.getColumnLabel:enabled
rsmd.getColumnName :enabled
rsmd.getColumnType :1
rsmd.getColumnTypeName:CHAR


Problem occurs because Hibernate expects VARCHAR, and not CHAR. This is why I got error message in the first place:

Code:
javax.persistence.PersistenceException: org.hibernate.HibernateException: Wrong column type: attr_type, expected: varchar(2)


seam-gen generated attribute like this:

Code:
   @Column(name = "domain", length = 2)
   @Length(max = 2)
   public String getEnabled() {
      return this.enabled;
   }


I think that Hibernate can't convert CHAR to VARCHAR it needs. Char behavior should be fixed.

There is also a small issue hidden behind big issue: seam-gen sets length to 2, and it is actually one.

Second problem: seam-gen, JPA and user types

User type mapping was not put in generated files, not in bean as TypeDef, not in configuration files, so application fails if I add user type to reveng.

I did it like this:

Code:
<hibernate-reverse-engineering>
    <table
            catalog="configuration"
            name="userdb_domain_acl">
        <column name="enabled" type="com.siemens.msm.model.mapping.BooleanEnumType" />
    </table>
</hibernate-reverse-engineering>


If you need more details, please explain exactly what details do you need.[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 7:12 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
zeljko_t wrote:
First problem: char handling

In simplest solution, enums don't have to be treated as enums at all, because MySQL JDBC driver reports them as simple java.sql.Types CHAR field. Here is printout of my test application (ResultSetMetaData from simple select statement):

Code:
rsmd.getColumnClassName  :java.lang.String
rsmd.getColumnDisplaySize:1
rsmd.getColumnLabel:enabled
rsmd.getColumnName :enabled
rsmd.getColumnType :1
rsmd.getColumnTypeName:CHAR


Problem occurs because Hibernate expects VARCHAR, and not CHAR. This is why I got error message in the first place:

Code:
javax.persistence.PersistenceException: org.hibernate.HibernateException: Wrong column type: attr_type, expected: varchar(2)



This error is schemavalidator; not hibernate core as such.

Quote:
seam-gen generated attribute like this:

Code:
   @Column(name = "domain", length = 2)
   @Length(max = 2)
   public String getEnabled() {
      return this.enabled;
   }


I think that Hibernate can't convert CHAR to VARCHAR it needs. Char behavior should be fixed.

There is also a small issue hidden behind big issue: seam-gen sets length to 2, and it is actually one.


well, I would assume that the driver have reported that it is type CHAR and has a length 2 thus it is actually mapped correctly - namely a String of length 2.

Maybe there is a mismatch between how mysql maps between their propritary enum type and the SQL types defined in java.sql.Types.

Quote:
Second problem: seam-gen, JPA and user types

User type mapping was not put in generated files, not in bean as TypeDef, not in configuration files, so application fails if I add user type to reveng.

I did it like this:

Code:
<hibernate-reverse-engineering>
    <table
            catalog="configuration"
            name="userdb_domain_acl">
        <column name="enabled" type="com.siemens.msm.model.mapping.BooleanEnumType" />
    </table>
</hibernate-reverse-engineering>


If you need more details, please explain exactly what details do you need.[/code]


maybe hibernate tools jpa generation does not put a typedefinition. please report that in jira (if you can verify that)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 7:49 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
max wrote:
well, I would assume that the driver have reported that it is type CHAR and has a length 2 thus it is actually mapped correctly - namely a String of length 2.

Maybe there is a mismatch between how mysql maps between their propritary enum type and the SQL types defined in java.sql.Types.

I found possible source of problem. MySQL driver reports different data in ResultSetMetaData and DatabaseMetaData.

ResultSetMetaData

rsmd.getColumnType :1
rsmd.getColumnTypeName:CHAR
rsmd.getColumnDisplaySize:1

DatabaseMetaData

DATA_TYPE=1
TYPE_NAME=enum
COLUMN_SIZE=2

Is it possible to force tools/core to use ResultSetMetaData?
Or maybe you can do some changes in MySQL dialect?
Quote:
maybe hibernate tools jpa generation does not put a typedefinition. please report that in jira (if you can verify that)

I'll do that.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 7:54 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
why would I use resultsetmetadata - I don't use queries to figure out the types and they are incorrect/imprecise in my opinion. mysql should fix their inconsistencies.

...and all of this is fixable via reveng.xml!

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 10:33 am 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
max wrote:
why would I use resultsetmetadata - I don't use queries to figure out the types and they are incorrect/imprecise in my opinion. mysql should fix their inconsistencies.

Until then, seam-gen doesn't work with MySQL, although I agree it is their fault.

max wrote:
...and all of this is fixable via reveng.xml!

Great! How?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 09, 2007 11:53 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
<type-mapping sql-type="CHAR" length="2" hibernate-type="string"/>

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 10, 2007 12:18 pm 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
max wrote:
<type-mapping sql-type="CHAR" length="2" hibernate-type="string"/>


This can't be parsed, so I put this :
Code:
<hibernate-reverse-engineering>
   <type-mapping>
      <sql-type jdbc-type="CHAR" length="2" hibernate-type="string"/>
   </type-mapping>
</hibernate-reverse-engineering>

and got this error:

Code:
13:49:31,397 INFO  [TableMetadata] table found: configuration.userdb_domain_acl
13:49:31,397 INFO  [TableMetadata] columns: [id, enabled, tablename, domain]
13:49:31,397 WARN  [ServiceController] Problem starting service persistence.units:ear=msmgui.ear,unitName=msmgui
javax.persistence.PersistenceException: org.hibernate.HibernateException: Wrong column type: enabled, expected: varchar(
2)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:698)
        at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:127)
        at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:264)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)


Property in bean looks like this:

Code:
@Column(name = "enabled", length = 2)
   @Length(max = 2)
   public String getEnabled() {
      return this.enabled;
   }


I also tried this to check is column matched correctly:
reveng.xml:
Code:
   <type-mapping>
      <sql-type jdbc-type="CHAR" length="2" hibernate-type="long"/>
   </type-mapping>

bean:
Code:
   @Column(name = "enabled", length = 2)
   @Length(max = 2)
   public long getEnabled() {
      return this.enabled;
   }

error:
Code:
14:49:16,469 INFO  [TableMetadata] table found: configuration.userdb_domain_acl
14:49:16,469 INFO  [TableMetadata] columns: [id, enabled, tablename, domain]
14:49:16,469 WARN  [ServiceController] Problem starting service persistence.units:ear=msmgui.ear,unitName=msmgui
javax.persistence.PersistenceException: org.hibernate.HibernateException: Wrong column type: enabled, expected: bigint
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:698)
        at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:127)


Funny thing, regular char columns work fine.

I don't know enough about Hibernate internals to pinpoint problem.

I have one suggestion, though: exception should state not just expected type, but also received. That will make analysis easier.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 10, 2007 1:01 pm 
Newbie

Joined: Mon Jan 08, 2007 5:10 am
Posts: 11
max wrote:
maybe hibernate tools jpa generation does not put a typedefinition. please report that in jira (if you can verify that)


I added this issue to JIRA: http://opensource.atlassian.com/project ... se/HBX-849


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 3:16 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
ok so mysql reports "funny" things here and schemavalidator is to rigid.

e.g. mysql probably reports CHAR(2) and hibernate expect that the String should be a VARCHAR(2) ..........

so to fix this we need to improve schemavalidator to not be so rigid on something that is not completly wrong.

For you to workaround it disable schemavalidator.

_________________
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.  [ 17 posts ]  Go to page 1, 2  Next

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.