2010-06-19 4 views
2

J'ai une entité de projet et une entité de groupe. Je peux obtenir un projet par nom en utilisant la méthode de lecture suivante de DAO:MySQLSyntaxErrorException bien que tout semble bien (Hibernate)

public Project getProject(String name){ 
    Project project = null; 

    DetachedCriteria criteria = DetachedCriteria.forClass(Project.class); 
    criteria.add(Restrictions.eq("name", name)); 
    List<Project> projects = getHibernateTemplate().findByCriteria(criteria); 
    if ((projects != null) && (projects.size() > 0)) { 
     project = (Project)projects.get(0); 
    } 
    return project; 
} 

Alors que cette même construction ne fonctionne pas pour le groupe DAO:

public Group getGroup(String name){ 
    Group group = null; 

    DetachedCriteria criteria = DetachedCriteria.forClass(Group.class); 
    criteria.add(Restrictions.eq("name", name)); 
    List<Group> groups = getHibernateTemplate().findByCriteria(criteria); 
    if ((groups != null) && (groups.size() > 0)) { 
     group = (Group)groups.get(0); 
    } 
    return group; 
} 

Voici la trace de la pile qui va (apparaît quand je tente de créer un nouveau groupe, un groupe avec le nom fourni est tiré par les cheveux pour vérifier si un tel groupe existe déjà et jeter une exception le cas échéant):

com.mysql.jdbc.exceptions.jdbc4. MySQLSyntaxErrorException: Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version du serveur MySQL pour la syntaxe droit d'utiliser près de « groupe this_ où this_.name = » new_group « » à la ligne 1 sun.reflect.NativeConstructorAccessorImpl.newInstance0 (natif méthode) sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) java.lang.reflect.Constructor.newInstance (Constructor.java:513) com. mysql.jdbc.Util.handleNewInstance (Util.java:409) com.mysql.jdbc.Util.getInstance (Util.java:384) com.mysql.jdbc.SQLError.createSQLException (SQLError.java:1054) com.mysql.jdbc.MysqlIO.checkErrorPacket (MysqlIO.java:3562) com.mysql.jdbc.MysqlIO.checkErrorPacket (MysqlIO.java:3494) com.mysql.jdbc.MysqlIO.sendCommand (MysqlIO.java:1960) com.mysql.jdbc.MysqlIO.sqlQueryDirect (MysqlIO.java:2114) com.mysql.jdbc.ConnectionImpl.execSQL (ConnectionImpl.java:2696) com.mysql.jdbc.PreparedStatement.executeInternal (PreparedStatement.java:2105) com.mysql.jdbc.PreparedStatement.executeQuery (PreparedStatement.java:2264) org.hibernate.jdbc.AbstractBatcher.getResultSet (AbstractBatcher.java: 187) org.hibernate.loader.Loader.getResultSet (Loader.java:1791) org.hibernate.loader.Loader. doQuery (Loader.java:674) org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections (Loader.java:236) org.hibernate.loader.Loader.doList (Loader.java:2217) org.hibernate.loader.Loader .listIgnoreQueryCache (Loader.java:2108) org.hibernate.loader.Loader.list (Loader.java:2103) org.hibernate.loader.criteria.CriteriaLoader.list (CriteriaLoader.java:94) org.hibernate. impl.SessionImpl.list (SessionImpl.java:1570) org.hibernate.impl.CriteriaImpl.list (CriteriaImpl.java:283) org.springframework.orm.hibernate3.HibernateTemplate $ 35.doInHibernate (HibernateTemplate.java:984) org.springframework.orm.hibernate3.HibernateTemplate.execute (HibernateTemplate.java:372) org.spring framework.orm.hibernate3.HibernateTemplate.findByCriteria (HibernateTemplate.java:974) org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria (HibernateTemplate.java:967) pl.edu.agh.adam.core.projects.dao. GroupDAO.getGroup (GroupDAO.java:65) pl.edu.agh.adam.core.projects.GroupService.createGroup (GroupService.java:76) pl.edu.agh.adam.core.projects.web.CreateGroupBean. create (CreateGroupBean.java:80) sun.reflect.NativeMethodAccessorImpl.invoke0 (natif , méthode) sun.reflect.NativeMethodAccessorImpl.invoquer (NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke (Method.java:597) com.sun.el.parser.AstValue .invoke (AstValue.java:234) com.sun.el.MethodExpressionImpl.invoke (MethodExpressionImpl.java:297) org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke (TagMethodExpression.java:83) javax.faces.component._MethodExpressionToMethodBinding.invoke (_MethodExpressionToMethodBinding.java:88) org.apache.myfaces.application.ActionListenerImpl.processAction (ActionListenerImpl.java:100) javax.faces.component.UICommand.broadcast (UICommand.java: 120) javax.faces.component.UIViewRoot._broadcastAll (UIView Root.java:890) javax.faces.component.UIViewRoot.broadcastEvents (UIViewRoot.java:234) javax.faces.component.UIViewRoot._process (UIViewRoot.java:1202) javax.faces.component.UIViewRoot.processApplication (UIViewRoot.java:623) org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute (InvokeApplicationExecutor.java:35) org.apache.myfaces.lifecycle.LifecycleImpl.executePhase (LifecycleImpl.java:143) org.apache. myfaces.lifecycle.LifecycleImpl.execute (LifecycleImpl.java:93) javax.faces.webapp.FacesServlet.service (FacesServlet.java:189) org.primefaces.webapp.filter.FileUploadFilter.doFilter (FileUploadFilter.java:79) org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal (O penSessionInViewFilter.java:198) org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:76)

Voici les entités (accesseurs omis):

@Entity 
@Table(name = "group") 
public class Group implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Transient 
    public static final String REF = "Group"; 

    @ManyToMany(targetEntity = pl.edu.agh.adam.core.account.hibernate.User.class) 
    @JoinTable(name = "group_user", joinColumns = @JoinColumn(name = "group_id"), inverseJoinColumns = @JoinColumn(name = "user_id")) 
    Set<User> users; 

    public Set<User> getUsers() { 
     return users; 
    } 

    public void setUsers(Set<User> users) { 
     this.users = users; 
    } 

    @ManyToMany(targetEntity = pl.edu.agh.adam.core.projects.hibernate.Role.class) 
    @JoinTable(name = "project_group_role", joinColumns = @JoinColumn(name = "group_id")) 
    @MapKeyJoinColumn(name = "project_id") 
    Map<Project, Role> projectRoles; 

    @Transient 
    public static final String PROP_ID = "id"; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name = "group_id") 
    private Long id; 

    @Transient 
    public static final String PROP_NAME = "name"; 
    @Column(name = "name", length = 25, unique = true, nullable = false) 
    private String name; 

    @Transient 
    public static final String PROP_PASSWORD = "password"; 

    @Column(name = "password", length = 40) 
    private String password; 

    @Transient 
    public static final String PROP_SUBSCRIBABLE = "subscribable"; 

    @Column(name = "subscribable") 
    private Boolean subscribable; 
} 

Le une autre (en fonction one):

@Entity 
@Table(name = "project") 
public class Project implements Serializable { 

private static final long serialVersionUID = 1L; 

@Transient 
public static final String REF = "Project"; 

@ManyToMany(targetEntity = pl.edu.agh.adam.core.projects.hibernate.Tag.class) 
@JoinTable(name = "project_tag", joinColumns = @JoinColumn(name = "project_id"), inverseJoinColumns = @JoinColumn(name = "tag_id")) 
private List<Tag> tags; 

@ManyToMany(targetEntity = pl.edu.agh.adam.core.projects.hibernate.Group.class) 
@JoinTable(name = "project_group_role", 
     joinColumns = @JoinColumn(name = "project_id"), 
     inverseJoinColumns = @JoinColumn(name = "group_id")) 
private Set<Group> groups; 

@ManyToMany(targetEntity = pl.edu.agh.adam.core.projects.hibernate.Role.class) 
@JoinTable(name = "project_group_role", 
     joinColumns = @JoinColumn(name = "project_id"), 
     inverseJoinColumns = @JoinColumn(name = "role_id")) 
private Set<Role> roles; 


@Transient 
public static final String PROP_ID = "id"; 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
@Column(name = "project_id") 
private Long id; 

@Transient 
public static final String PROP_NAME = "name"; 
@Column(name = "name", length = 60, unique = true, nullable = false) 
private String name; 

@Transient 
public static final String PROP_SHORTNAME = "shortname"; 

@Column(name = "shortname", length = 25, unique = true) 
private String shortname; 

@Transient 
public static final String PROP_HOMEPAGE = "homepage"; 
@Column(name = "homepage", length = 60) 
private String homepage; 

@Transient 
public static final String PROP_DESCRIPTION = "description"; 
@Column(name = "description", columnDefinition = "LONGTEXT") 
private String description; 

    } 

de plus, les structures de table: groupe: -group_id int (11) incrémentation automatique, non null -nom varchar (25) unique, non null -password varchar (40) -subscribable tinyint (1)

projet

-project_id int (11) incrémentation automatique, non null -nom varchar (60) unique, non nul -shortname varchar (25) -Homepage varchar (25) -description texte

Je suis retourné sur la journalisation des requêtes de mise en veille prolongée à System.out; des documents suivants sont produits:

select 
    this_.project_id as project1_3_0_, 
    this_.description as descript2_3_0_, 
    this_.homepage as homepage3_0_, 
    this_.name as name3_0_, 
    this_.shortname as shortname3_0_ 
from 
    project this_ 
where 
    this_.name=? 

Et ne fonctionne pas un:

select 
    this_.group_id as group1_4_0_, 
    this_.name as name4_0_, 
    this_.password as password4_0_, 
    this_.subscribable as subscrib4_4_0_ 
from 

group this_ where 
    this_.name=? 

Qu'est-ce qui se passe ?? :(

+0

Est-ce que la deuxième exécution de la requête lorsqu'il est collé dans un client SQL? –

+0

Non ce n'est pas le cas, ce qui n'est pas vraiment une surprise, même si je ne peux pas dire en un coup d'œil, ce qui ne va pas. De plus - comment puis-je faire en sorte que hibernate en génère une autre? – sammy

+0

Je ne m'attendais pas à ce que cela fonctionne, mais il est plus facile de "déboguer" quelque chose dans un client SQL (supprimer les alias, supprimer les colonnes, etc.). Quoi qu'il en soit, je pense que j'ai trouvé le problème. –

Répondre

1

Je ne tache qui immédiatement, mais group est un mot-clé réservé de sorte que la requête générée est en effet incorrect Utilisez un autre nom de table pour l'entité Group Par exemple:..

@Entity 
@Table(name = "groups") 
public class Group implements Serializable { 

    //... 
} 
+0

Merde moi si ce n'est pas correct. Y a-t-il un autre usage du mot GROUP en dehors de GROUP BY? Sinon, le mot devrait être utilisable. Je suis assez réticent quand il s'agit de modifier la base de données, donc j'ai fait ceci: '@Table (name =" \ 'group \' ")' Maintenant, tout fonctionne comme un charme. Merci beaucoup de repérer ceci pour moi :) – sammy

+0

@sammy: En effet, cela fonctionnera (et est en fait mieux si vous ne voulez pas changer la base de données). Personnellement, j'essaie d'éviter les mots-clés réservés, mais votre solution est correcte. –

+0

Ah, vous m'avez aidé aussi. Mon mot réservé était "index". :-) –

Questions connexes