Mantis - Resin
Viewing Issue Advanced Details
3081 block always 11-17-08 19:09 12-15-08 15:11
dicr  
ferg  
normal  
closed 3.2.1  
fixed  
none    
none 4.0.0  
0003081: @ManyToOne@JoinColumn SQL column name generation BUG
Resin correctly generated name of SQL table column for @ManyToOne@Column bean property, but generate empty ('') column name for @ManyToOne@JoinColumn.

Example to reproduce:

@Entity
public class UserDO {
    @Id private long id;

    public UserDO() {
    }
}

@Entity
public class LoginDO {
    @Id private long id;

    @ManyToOne @JoinColumn(insertable=false) private UserDO user;
    
    public LoginDO() {
    }
}

Pay attention, that @JoinColumn used without 'name' parameter.
If there no tables in database yet and <ejb-server> used with 'create-database-schema="true"' parameter, then Amber produce this SQL to create tables:

[04:40:36.780] {resin-114} jdbc/test.0.0:exn-executeUpdate(create table LoginDO (
[04:40:36.780] {resin-114} id BIGINT auto_increment primary key,
[04:40:36.780] {resin-114} BIGINT
[04:40:36.780] {resin-114} )) -> com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to
 your MySQL server version for the right syntax to use near 'BIGINT
[04:40:36.780] {resin-114} )' at line 3

The name of generated column must be "user_id" and type BIGINT, but actually generated name is '' (empty), then SQL systax is incorrect:

  BIGINT
instead of
  user_id BIGINT

If tables in database is already created by hand, then error occur upon loading beans:

[04:47:36.029] {http--8080-20} com.caucho.config.ConfigException: '' is not a valid database column in table 'LoginDO'. Either the table needs to be created or the create-database-tables attribute must be set.
[04:47:36.029] {http--8080-20}
[04:47:36.029] {http--8080-20} select from LoginDO where 1=0
[04:47:36.029] {http--8080-20}
[04:47:36.029] {http--8080-20} com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to y
our MySQL server version for the right syntax to use near 'from LoginDO where 1=0' at line 1
Workarounds:

1) specify 'name' attribute in @Joincolumn:

    @ManyToOne @JoinColumn(name="user_id", insertable=false) private UserDO user;

In this case Amber generate right SQL and all work fine, but EJB3 specification says that attribute 'name' for @JoinColumn annotation is optional and:

ejb-3_0-fr-spec-persistence.pdf
9.1.6 JoinColumn Annotation
"If there is a single join column, and if the name annotation member is missing, the join column name is
formed as the concatenation of the following: the name of the referencing relationship property or field
of the referencing entity; "_"; the name of the referenced primary key column."

2) use @Column instead of @JoinColumn

    @ManyToOne @Column(insertable=false) private UserDO user;

In this case all works correctly, but I don't know is this correct to use simple @Column in @ManyToOne instead of @JoinColumn ? In this case Amber generate correct name for 'user' property and produce correct SQL for creating table:

[04:59:24.011] {http--8080-21} jdbc/test.0.0:executeUpdate(create table LoginDO (
[04:59:24.011] {http--8080-21} id BIGINT auto_increment primary key,
[04:59:24.011] {http--8080-21} user_id BIGINT
[04:59:24.011] {http--8080-21} )) -> 0
[04:59:24.011] {http--8080-21} jdbc/test.0.0:close()

And also correct SQL produced upon bean loading:

[05:02:40.092] {http--8080-22} allocate PoolItem[jdbc/test,0,ManagedConnectionImpl]
[05:02:40.092] {http--8080-22} jdbc/test.0.3:createStatement()
[05:02:40.092] {http--8080-22} jdbc/test.0.3:executeQuery(select user_id from LoginDO where 1=0)
[05:02:40.092] {http--8080-22} jdbc/test.0.3:close()

Notes
(0003552)
dicr   
11-21-08 08:37   
In comparision to Resin 3.1.7a, the behaviour has changed in today release of Resin 3.1.8. From now, workaround 2) does not work anymore. And no related changes in the changelog. Cool :)

[18:17:12.155] {main} com.caucho.config.ConfigException: example.LoginDO.user: user may not have a @javax.persistence.Column annotation. @ManyToOne does not allow @javax.persistence.Column.
[18:17:12.155] {main} at com.caucho.amber.cfg.AbstractConfigIntrospector.error(AbstractConfigIntrospector.java:268)
[18:17:12.155] {main} at com.caucho.amber.cfg.AbstractConfigIntrospector.validateAnnotations(AbstractConfigIntrospector.java:247)
[18:17:12.155] {main} at com.caucho.amber.cfg.BaseConfigIntrospector.introspectField(BaseConfigIntrospector.java:1370)
[18:17:12.155] {main} at com.caucho.amber.cfg.BaseConfigIntrospector.introspectFields(BaseConfigIntrospector.java:1273)
[18:17:12.155] {main} at com.caucho.amber.cfg.EntityIntrospector.introspect(EntityIntrospector.java:173)
[18:17:12.155] {main} at com.caucho.amber.cfg.AmberConfigManager.introspect(AmberConfigManager.java:86)
[18:17:12.155] {main} at com.caucho.amber.manager.AmberPersistenceUnit.addEntityClass(AmberPersistenceUnit.java:506)
[18:17:12.155] {main} at com.caucho.amber.cfg.PersistenceUnitConfig.init(PersistenceUnitConfig.java:324)

(0003646)
ferg   
12-15-08 15:11   
php/0h0d