web-dev-qa-db-fra.com

Erreur MVC de MyBatis Spring: instruction liée non valide (introuvable)

Voici la trace de la pile lorsque j'essaie d'exécuter une requête simple à l'aide de MyBatis: 

org.Apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.my.package.persistence.BrandMapper.getBrand
    org.Apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.Java:189)
    org.Apache.ibatis.binding.MapperMethod.<init>(MapperMethod.Java:43)
    org.Apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.Java:58)
    org.Apache.ibatis.binding.MapperProxy.invoke(MapperProxy.Java:51)
    com.Sun.proxy.$Proxy25.getBrand(Unknown Source)
    com.my.package.service.BrandService.getBrand(BrandService.Java:18)
    com.my.package.service.BrandService$$FastClassBySpringCGLIB$$1140c60a.invoke(<generated>)
    org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.Java:204)
    org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:649)
    com.my.package.service.BrandService$$EnhancerBySpringCGLIB$$ea6f89cd.getBrand(<generated>)
    com.my.package.controller.HomeController.getBrands(HomeController.Java:28)
    Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    Java.lang.reflect.Method.invoke(Method.Java:483)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:221)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:137)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:110)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:777)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:706)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.Java:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.Java:729)
    org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52)

J'utilise la syntaxe Javaconfig au lieu de la configuration XML. Voici mon PersistenceConfig:

@Configuration
@EnableTransactionManagement
@MapperScan("com.my.package.persistence")
public class PersistenceConfig {

    @Bean
    public DataSource dataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        try {
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql//localhost:3306/db");
            dataSource.setUsername("dbuser");
            dataSource.setPassword("dbpassword");
        } catch (Exception e) {
            System.out.print(e);
        }
        return dataSource;
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setTypeAliasesPackage("com.my.package.domain");
        return sessionFactory;
    }
}

Voici mon contrôleur:

@Controller
public class HomeController {

    private static Logger logger = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    private BrandService brandService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index() {
        return "index";
    }

    @RequestMapping(value = "/brands", method = RequestMethod.GET)
    public String getBrands(Model model) {
        model.addAttribute("brands",brandService.getBrand(1));
        return "brands";
    }

}

Voici mon interface Brand Mapper:

public interface BrandMapper {

    Brand getBrand(int id);

    Brand getBrandByName(String name);

    List<Brand> getBrandList();

    void addBrand(Brand brand);

    void updateBrand(Brand brand);

    void deleteBrand(int id);

}

Voici mon XML BrandMapper:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.my.package.persistence.BrandMapper">

    <select id="getBrand" resultType="Brand" parameterType="int">
        SELECT id, name
        FROM brand
        WHERE id = #{id};
    </select>

    <select id="getBrandByName" resultType="Brand" parameterType="String">
        SELECT id, name
        FROM brand
        WHERE name = #{name};
    </select>

    <select id="getBrandList" resultType="Brand">
        SELECT id, name
        FROM brand;
    </select>

    <insert id="addBrand" parameterType="Brand">
        INSERT INTO brand (id, name)
        VALUE (#{id}, #{name})
    </insert>

    <update id="updateBrand" parameterType="Brand">
        UPDATE brand
        SET
        name = #{name}
        where id = #{id}
    </update>

    <delete id="deleteBrand" parameterType="int">
        DELETE FROM brand
        WHERE id = #{id}
    </delete>

</mapper>

J'ai fait des recherches, mais aucune des solutions n'a fonctionné pour moi. Les fichiers My XML Mapper sont situés sous les ressources dans un package nommé "com.my.package.persistence".

Est-ce que quelqu'un a une idée de ce qui ne va pas ici? 

Merci d'avance

5
Jail

Essayez de vérifier le fichier mybatis-conf.xml (quel que soit le nom de votre fichier appelé) et voyez si vous avez votre mappeur xml comme ceci:


<mappers> 
    <mapper resource="BrandMapper.xml">
<mappers>

Si vous aviez exécuté le JUNIT du code de service de base de données, cela aurait fonctionné. Par conséquent, je crois que c’est le probmlem lorsqu’un fichier WAR est généré. À partir de votre configuration, Mapper.Java et * Mapper.xml indiquent le même emplacement. Ainsi, lorsque war est géréné, le chemin du dossier pour les fichiers Java et xml serait WEB-INF/classes/com/my/package/persistence. Cependant, le fichier * .xml n'est pas copié à l'emplacement. Une solution consiste à configurer votre script de construction de manière à copier les fichiers xml également ou autrement (ce que je préférerais) pour créer un répertoire sqlmap dans le répertoire resources et copier tous les fichiers mappeur xml dans le répertoire et pointer vers l'emplacement du fichier mapper à l'aide de sessionFactory.setMapperLocations et une fois war le fichier est généré, assurez-vous que le répertoire sqlmap est présent dans le répertoire WEB-INF/classes

1
Karthik Prasad

Message d'erreur :

org.Apache.ibatis.binding.BindingException: Invalid bound statement (not found):

Très probablement en raison d'un mauvais mappeur Syntaxe de requête . J'ai eu ce problème plusieurs fois et chaque fois que l'erreur est causée par une syntaxe incorrecte de la requête écrite dans le fichier mapper xml et les fichiers d'interface. Je vous suggère de

  • Revérifiez votre requête correctement, ce qui est principalement la raison de cette erreur.
  • Configuration => Peut également être dû à une configuration non valide des fichiers de mappeur (interface et xml) dans les fichiers de configuration.
  • Ne maven clean, maven installer (reconstruire) puis redémarrer le serveur
1
Lucky

J'ai eu ce message d'erreur exact, s'est avéré être le chemin de l'espace de noms dans le fichier mappeur xml, j'avais changé le nom du paquet dans le fichier d'interface Java mais j'ai oublié de mettre à jour le nom du paquet dans le mappeur xml, un peu étrange. Mis à jour l'espace de noms du paquet et hop!

0
derek

Vous devez indiquer les emplacements du mappeur lors de l’initialisation de sqlSessionFactory:

    @Autowired
    private ResourceLoader resourceLoader;

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        //sessionFactory.setTypeAliasesPackage("com.my.package.domain");
        sessionFactory.setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).
            getResources("classpath:path/to/mappers/*.xml"));
        return sessionFactory;
   }

Dans votre cas, remplacez "classpath: chemin/vers/mappers/*. Xml" avec classpath: com/mon/package/persistence/*. Xml

J'espère que ceci vous aidera.

0
JackJonesAngel

Votre fichier de mappeur doit figurer dans le même package que le fichier * Repo.Java. Vérifiez également l'espace de noms du mappeur.

0
Sravan

Supprimez le ; de la requête:

<select id="getBrand" resultType="Brand" parameterType="int">
    SELECT id, name
    FROM brand
    WHERE id = #{id}
</select>
0
Akash Rajbanshi

Je suppose que vous avez peut-être besoin d'un @Alias ​​annotation:

@Alias ​​("Marque") Classe Brand { ... }

c'est la première chose qui me vient à l'esprit, espérons que cela aide!

0
S_intg