J'ai un problème avec ma déclaration préparée mais je ne peux pas savoir où se trouve l'erreur. J'essaie d'insérer un lien URI dans la base de données.
@Repository
public interface LoggerDao extends CrudRepository<Logger, Long> {
@Query("select t from Logger t where t.user.id=?#{principal.id}")
List<Logger> findAll();
@Modifying
@Query(value = "insert into Logger t (t.redirect, t.user.id) VALUES (:insertLink,?#{principal.id})", nativeQuery = true)
@Transactional
void logURI(@Param("insertLink") String insertLink);
Erreur
2017-03-11 19:52:59.157 WARN 65154 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 42001, SQLState: 42001
2017-03-11 19:52:59.157 ERROR 65154 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Syntax error in SQL statement "INSERT INTO LOGGER T[*] (T.REDIRECT, T.USER.ID) VALUES (?,?) "; expected "., (, DIRECT, SORTED, DEFAULT, VALUES, SET, (, SELECT, FROM"; SQL statement:
insert into Logger t (t.redirect, t.user.id) VALUES (?,?) [42001-190]
2017-03-11 19:52:59.181 ERROR 65154 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [insert into Logger t (t.redirect, t.user.id) VALUES (?,?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement] with root cause
org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "INSERT INTO LOGGER T[*] (T.REDIRECT, T.USER.ID) VALUES (?,?) "; expected "., (, DIRECT, SORTED, DEFAULT, VALUES, SET, (, SELECT, FROM"; SQL statement:
insert into Logger t (t.redirect, t.user.id) VALUES (?,?) [42001-190]
at org.h2.engine.SessionRemote.done(SessionRemote.Java:624) ~[h2-1.4.190.jar:1.4.190]
at org.h2.command.CommandRemote.prepare(CommandRemote.Java:68) ~[h2-1.4.190.jar:1.4.190]
at org.h2.command.CommandRemote.<init>(CommandRemote.Java:45) ~[h2-1.4.190.jar:1.4.190]
at org.h2.engine.SessionRemote.prepareCommand(SessionRemote.Java:494) ~[h2-1.4.190.jar:1.4.190]
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.Java:1188) ~[h2-1.4.190.jar:1.4.190]
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.Java:72) ~[h2-1.4.190.jar:1.4.190]
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.Java:276) ~[h2-1.4.190.jar:1.4.190]
at org.Apache.Tomcat
J'ai réussi à résoudre le problème. J'ai ajouté un identifiant aux paramètres afin que je puisse passer l'identifiant de l'utilisateur, en utilisant Principal dans le contrôleur.
@Repository
public interface LoggerDao extends CrudRepository<Logger, Long> {
@Query("select t from Logger t where t.user.id=?#{principal.id}")
List<Logger> findAll();
@Modifying
@Query(value = "insert into Logger (redirect,user_id) VALUES (:insertLink,:id)", nativeQuery = true)
@Transactional
void logURI(@Param("insertLink") String insertLink, @Param("id") Long id);
Il y a un moyen de faire des insertions en utilisant des requêtes obj (pas natives) (en utilisant @Query & @Modifying) mais cela dépend de la base de données que vous utilisez. Ci-dessous a fonctionné pour moi dans Oracle (en utilisant Dual table):
@Repository
public interface DualRepository extends JpaRepository<Dual,Long> {
@Modifying
@Query("insert into Person (id,name,age) select :id,:name,:age from Dual")
public int modifyingQueryInsertPerson(@Param("id")Long id, @Param("name")String name, @Param("age")Integer age);
}
Voici un lien qui montre en bas quel support de db sélectionnez stmts sans clause from: http://modern-sql.com/use-case/select-without-from