Tag Archives: MyBatis

[Solved] Ideal Integrate Mybatis.xml File Error: BindingException: Invalid bound statement (not found):

Screenshot of error reporting

Checked the corresponding namespace

Corresponding target directory

Next, the path of the configuration file is checked

When it is found that none of the four conventional methods can solve the problem, consider whether it is the
POM file screenshot caused by jar package conflict

Sure enough, I use mybatis plus, but I use the startup jar package of mybatis. Replace it with mybatis plus boot starter, and comment out all related mybatis. The problem is solved.

[Solved] Mybatis error: attempted to return null from a method with a primitive return type (int)

1. Origin of the problem

When viewing the log, I found that a line of error message was printed in the log:

The data of assembled pets that have been released is abnormal — & gt; Mapper method ‘applets. user. mapper. xxxMapper. xxxmyRank attempted to return null from a method with a primitive return type (int).

The meaning is well understood. The query method of xxxmyrank in a mapper file returns null, but it needs to return an int type number, so an error is reported.

2. Problem analysis

Fdafdsaf query is a simple query used to query a ranking. If you query the ranking yourself, you can use int type to receive it. At the beginning of the test, there was no problem, but after the project was really launched

Report this problem before you know that this problem exists in the previously written code. The reason for this problem is that the database does not query the corresponding data, so it returns a null value. When you write your own code, you use the int type receive. As shown in the figure below:

3. Solution

After finding the cause of the problem, it is easy to solve it. Change the received int type to the wrapper type integer type class for reception, so as to solve this problem. Because the integer type can be null, regardless of the specific value returned

Or a null value, can receive. Then, you can process the null value in the code, and the problem is solved.

Expansion: this method is mainly used in query. When writing custom numeric fields in Java code, it is best to use the wrapper type to receive them,

Byte,Boolean,Short ,Character,Integer,Long,Float,Double.

The principle is the same. If you query the entity class or use the entity class to accept the value passed by the front end, there may be no value null. At this time, using the wrapper type can solve this problem.

[Solved] mybatis Bulk Insert Error: Column count doesn‘t match value count at row 1

Mybatis batch insert problem

Incorrect wording:

INSERT INTO t_csm_customer_product(id, customer_code, product_code) values
<foreach collection="lists" close=")" open="(" index="i" item="cstProduct" separator=",">
    #{cstProduct.id},
    #{cstProduct.customerCode},
    #{cstProduct.productCode}
</foreach>

Error Messages: Error updating database…Cause: java.sql.SQLException: Column count doesn’t match value count at row 1
Print sql:

INSERT INTO table(id, name, value) values ( ?,?,?,?,?,?) 

The whole bracket is enclosed

The SQL we want:

INSERT INTO table(id, name, value) values ( ?,?,?),(?,?,?)  

Adjust XML to:

INSERT INTO t_csm_customer_product(id, customer_code, product_code) values
<foreach collection="lists" index="i" item="cstProduct" separator=",">
    (#{cstProduct.id},
    #{cstProduct.customerCode},
    #{cstProduct.productCode})
</foreach>

Missing parameter () in key foreach

[Solved] Mybatis Codes Error: java.lang.ClassNotFoundException: Cannot find class: com.mysql.jdbc.Driver

When reading the MySQL source code, download the source code, write a simple demo, run and report errors

java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: com.mysql.jdbc.Driver
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at org.apache.ibatis.demo.MybatisMain.main(MybatisMain.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

After checking online, most of them are the same as mysql-connector-java-x.x.x-bin.jar, but no matter what version of package I introduce, the problem still exists.

After step-by-step debugging, it is found that the place where the com.mysql.jdbc.driver class is loaded is the following method of org.apache.ibatis.io.classloaderwapper

Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
  for (ClassLoader cl : classLoader) {
    if (null != cl) {
      try {
        return Class.forName(name, true, cl);
      } catch (ClassNotFoundException e) {
        // we'll ignore this until all classloaders fail to locate the class
      }
    }
  }
  throw new ClassNotFoundException("Cannot find class: " + name);
}

But why can’t I load it?

So test it in the main method

public class MybatisMain {
  public static void main(String[] args) throws IOException
  {
    try {
      Class.forName("com.mysql.jdbc.Driver", true, Thread.currentThread().getContextClassLoader());
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }
}

As a result, it still can’t be loaded.

Conclusion:

Look at the POM file

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.24</version>
  <scope>test</scope>
</dependency>

Notice the <scope>test</scope> in the pom file, the problem lies here, comment out this line, the problem is solved.

[Solved] Mybatis Error: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableExc

org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: com.baizhi.entity.User
at org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:100)
atorg.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.io.NotSerializableException: com.baizhi.entity.User
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:96)
… 47 more

Reason: when using the L2 cache in mybatis, the entity class must be serialized. Implements serializable. My mapper file uses tags and the L2 cache provided by mybatis, so it must be serialized in my entity class

<?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.baizhi.dao.UserDao">
     <!-- The L2 cache is used here The entity class must implement the serialization interface -->
    <cache/>  
    <select id="selectAllUsers" resultType="User">
        select id,
               phone,
               password,
                name,
        from c_user
    </select>
</mapper>

Cannot change the executortype when there is an existing transaction [How to Solve]

Error content

org.springframework.dao.TransientDataAccessResourceException: Cannot change the ExecutorType when there is an existing transaction
	at org.mybatis.spring.SqlSessionUtils.sessionHolder(SqlSessionUtils.java:157)
	at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:91)
	at com.baomidou.mybatisplus.core.toolkit.sql.SqlHelper.sqlSessionBatch(SqlHelper.java:55)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.sqlSessionBatch(ServiceImpl.java:75)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveOrUpdateBatch(ServiceImpl.java:172)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveOrUpdateBatch(ServiceImpl.java:163)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$76535273.invoke(<generated>)

Actual use method (error example)

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResp saveOrUpdate(TestPlanParam param) {
        //add, update
============================================================
Omit the codes
============================================================
        //1.New, updated firefighting plans (now with additional master tables)
        this.saveOrUpdate(planEntity);
        Integer testPlanId = planEntity.getId();
        List<PlanTestTeamEntity> teamEntities=new ArrayList<>();
        List<PlanTestResourceEntity> resourceEntities=new ArrayList<>();

        //2.Add update firefighting team (bulk add schedule, need to hook up the id of the main table)
        teams.forEach(team->{
            PlanTestTeamEntity teamEntity=new PlanTestTeamEntity();
            BeanUtil.copyProperties(team,teamEntity);
            teamEntity.setFireFightTestPlanId(testPlanId);
            //planTestTeamService.saveOrUpdate(teamEntity); Solution, using an article-by-article update
            teamEntities.add(teamEntity);
        });
        //3.Add update of fire fighting supplies (bulk add schedule, need to hook up the id of the main table)
        resources.forEach(res->{
            PlanTestResourceEntity resourceEntity=new PlanTestResourceEntity();
            BeanUtil.copyProperties(res,resourceEntity);
            resourceEntity.setFireFightTestPlanId(testPlanId);
            //planTestResourceService.saveOrUpdate(resourceEntity); Solution, using an article-by-article update
            resourceEntities.add(resourceEntity);
        });
        planTestTeamService.saveOrUpdateBatch(teamEntities);
        planTestResourceService.saveOrUpdateBatch(resourceEntities);

        return BaseResp.success();
    }

Error reporting reason

Executortype cannot be changed when a transaction exists

Solution:

When batch updating, first check out all the updated objects, and then update them circularly

How to Solve Mybatis Chinese parameter error

A simple query, if there is Chinese in the parameters. As follows:

<select id="xxxx" resultType="hashmap">
    select * from talbe_a a where  a.kpeople = ${name} </select>

Error reporting:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00904: "Xiao Yaxuan": Identifier is invalid
...

Caused by: java.sql.SQLSyntaxErrorException: ORA-00904: "Xiao Yaxuan": Identifier is invalid
....

mybatis sql log

18:06:36,192 DEBUG JdbcTransaction:47 - Openning JDBC Connection
18:06:36,830 DEBUG PooledDataSource:47 - Created connection 1459361227.
18:06:36,843 DEBUG queryrealactormediatop:47 - ooo Using Connection [oracle.jdbc.driver.T4CConnection@56fc15cb]
18:06:36,843 DEBUG queryrealactormediatop:47 - ==>  Preparing: select * from table_a a where v1.kpeople = 萧亚轩 
18:06:36,961 DEBUG queryrealactormediatop:47 - ==> Parameters:

Note: “Xiao Yaxuan” has no single quotation marks around it, not “?” There is no value in the parameter list

 

The modification is actually very simple:

V1: change $to#

<select id="xxxx" resultType="hashmap">
    select * from talbe_a a where  a.kpeople = #{name} </select>

V2: Add ” single quotation mark

<select id="xxxx" resultType="hashmap">
    select * from talbe_a a where  a.kpeople = ‘${name}‘ </select>

#It’s just a string

$is not necessarily a string or other type

Error in mybatis mapping .XML File [How to Solve]

In the mybatis framework, the test is carried out in the Dao layer, and the console displays an error: the attribute “resulttype” must be declared for the element type “delete”

The SQL statement of the corresponding. XML file is:

The detailed error messages on the console are:

1. Attribute ‘resulttype’ must be declared for element type ‘Delete’

2.

Check the information on the Internet and say that every_In the sqlmapper.xml file, try to match each SQL statement to a namespace (the complete Java class of each Dao layer); As a result, the attempt was unsuccessful

Finally, simply_Delete the resulttype in the sqlmapper.xml file, and the test is successful; Delete as shown:

Successful test chart:

1 is to get the spring container

2 is the number of deleted data in the test (the number of deleted data in the first test is 1), and this result is the second test

 

[Solved] Mybatis Error: Invalid bound statement (not found)

Mybatis error reporting: there are many reasons for invalid bound statement (not found), but just like the error reporting prompt, the SQL statement in XML cannot be found. There are three types of error reporting:

The first: syntax error

Java Dao layer interface

public void delete(@Param("id")String id);

Mapper.xml file corresponding to Java

<?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="xxx.xxx.xxx.Mapper">
    <!-- Delete Datas -->
    <delete id="delete" parameterType="java.lang.String">
        DELETE FROM xxx WHERE id=#{id}
    </delete>
</mapper>

Check:

Is the method name (delete) in the interface consistent with id = "delete" in the XML file

Is the path in namespace = "XXX. XXX. XXX. Mapper" in the XML file consistent with the path in the interface file

Whether the parametertype type and resulttype types are accurate; Resultmap is different from resulttype

 

Second: compilation error

Navigate to the project path: under the error path in target \ classes \ , find out whether the corresponding XML file exists

(1) . if there is no corresponding XML file, you need to add the following code to pom.xml:

<build>
    <resources>
         <resource>
             <directory>src/main/java</directory>
             <excludes>
                 <exclude>**/*.java</exclude>
             </excludes>
         </resource>
         <resource>
             <directory>src/main/resources</directory>
             <includes>
                 <include>**/*.*</include>
             </includes>
        </resource>
    </resources>
</build>

Delete the files in the classes folder, recompile, and the corresponding XML file appears

(2) If there is an XML file, open the XML file and check whether the error part is consistent with the source file. If it is inconsistent,

first clear the files in the classes folder and execute the command: MVN clean clean the content and recompile it

 

Third: configuration error

There was a problem with the configuration path when specifying the scan package in the configuration file

for example, : the package name of the “basepackage” attribute in the spring configuration file must be specific to the package where the interface is located, and do not write the package of the parent level or higher, otherwise problems may occur; Cn. Dao and CN. * may also cause errors; During annotation scanning, packages may not be scanned

[Solved] Mybatis batch insert error: The incoming Table Format Data Stream (TDS) Remote Procedure Call…

Error message:

The incoming Table Format Data Stream (TDS) Remote Procedure Call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. The maximum should be 2100

Error analysis:

Due to too many SQL statement parameters spliced by mybatis

Solution:

Batch processing without mybatis

① Configuration file   applicationContext-mybatis.xml

  <!-- Solving mybatis batch insert -->
    <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
        <constructor-arg name="executorType" value="BATCH" />
    </bean>

②service import

    @Autowired
	private SqlSessionTemplate sst;

③ The self encapsulated method was used in the service for batch insert

	public Boolean insert(List<PDA_JWL_INTERFACE_H> inList,String zyh){
		// Get a new session with mode BATCH and auto-commit set to false
		// If auto-commit is set to true, it will not be possible to control the number of commits and will instead be submitted uniformly at the end, which may lead to a memory overflow
		SqlSession session = sst.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
		moMapper= session.getMapper(MOMapper.class);
		Map<String,Object> cc = new HashMap<>();
		
		try {
			for (PDA_JWL_INTERFACE_H in : inList) {
				moMapper.insert(in);
			}
			cc.put("zyh", zyh);
			moMapper.call(cc);
			session.commit();
			//Clearing the cache to prevent overflow
			session.clearCache();
			return true;
		} catch (Exception e) {
			session.rollback();
			return false;
		} finally {
			session.close();
		}
	}

 

End 9315;

	/**
	 * submit
	 */
	@RequestMapping(value="/tj", method = RequestMethod.POST,produces="application/json;charset=utf-8")
	@ResponseBody
	public Map<String,Object> tj(@RequestBody List<PDA_JWL_INTERFACE_H> tList,HttpServletRequest req){
		
		//Encapsulating the return value of a map
		Map<String,Object> m = new HashMap<>();
		
		
		//Decryption Certification
		String token = req.getParameter("token");
		String tk = MD5Utils.encode(CREKEY);
		System.out.println(tk);
		if(!token.equals(tk)){
			m.put("flag",Code.FLAG1.getIndex());
			m.put("erroCode", Code.ERROR1.getIndex());
			m.put("content", "");
			return m;
		}
		//Store the data to be placed in the intermediate table
		List<PDA_JWL_INTERFACE_H> inList = new LinkedList<>();
		
		// Job number, produced with UUID, unique number, distinguishes job type
		
		//Long t1 = System.currentTimeMillis();
		
		String zyh = UUID.randomUUID().toString();
		try {
			for (PDA_JWL_INTERFACE_H t : tList) {
				
				PDA_JWL_INTERFACE_H in = new PDA_JWL_INTERFACE_H();
				
				//Job number
				in.setZYH(zyh);
				// Order maker number: default current login ID (required, not shown)
				in.setZDRH(t.getZDRH());
				//Things type: default "Purchase Inbound" (required, not shown)
				in.setSWLX(t.getSWLX());
				//Supplier number: required, not shown
				in.setGYSH(t.getGYSH());
				//Supplier: The company number in the view is the same as the company number of this job
				in.setGYS(t.getGYS());
				//Company number: required, not shown
				in.setGSH(t.getGSH());
				//Warehouse number: required, not shown
				in.setCKH(t.getCKH());
				//Warehouse: the operator number in the view is the same as the current login ID
				in.setCK(t.getCK());
				//new warehouse number
				in.setXCKH(t.getXCKH());
				//new warehouse
				in.setXCK(t.getXCK());
				//claimers
				in.setLYR(t.getLYR());
				//new warehouse position number
				in.setXKWH(t.getXKWH());
				//new storage position
				in.setXKW(t.getXKW());
				//Purchase Type:Required
				in.setCGLX(t.getCGLX());
				//Purchaser: required
				in.setCGR(t.getCGR());
				//Stockroom number: required, not displayed
				in.setKWH(t.getKWH());
				// Warehouse location: the warehouse number in the view is the same as the warehouse number of this job
				in.setKW( t.getKW());
				//line number: automatically generate a non-repeating serial number for this job. app-side pass over
				in.setHH( t.getHH());
				//Item number: return the corresponding value directly after inputting the item number, which needs to be matched exactly. The company number and item type in the view are the same as the company number and purchase type of this job. (required)
				in.setWPH(t.getWPH());
				//Item name: display, not editable
				in.setWPMC(t.getWPMC());
				//spec: show, not editable
				in.setGG(t.getGG());
				//units: display, non-editable
				in.setDW(t.getDW());
				//production lot number: popup selection after entering keyword.
				in.setSCPH(t.getSCPH());
				//Grade: default First class (required)
				in.setDJI(t.getDJI());
				//Quantity: required
				in.setSL(t.getSL());
				//Number of pieces: Not required
				in.setJS(t.getJS());
				//Unit price: non-required, if it is empty or 0, only prompted, no control over subsequent operations.
				in.setDJ(t.getDJ());
				//amount: unit price*quantity, not editable.
				in.setJE(t.getJE());
				//Currency code: default RMB (required)
				in.setBBM(t.getBBM());
				//Tax rate: default 0.17 (required)
				in.setSLV(t.getSLV());
				// First level sector
				in.setYJBM(t.getYJBM());
				//Inventory source
				in.setPDLY(t.getPDLY());
				//lot number
				in.setPH(t.getPH());
				
				inList.add(in);
				
			}
			Boolean flag = moService.insert(inList,zyh); if(!flag){ int i = 1/0; }else{ /*Long t2 = System.currentTimeMillis(); System.out.println(t2-t1);*/ }
			
		} catch (Exception e) {
			e.printStackTrace();
			m.put("flag",Code.FLAG1.getIndex());
			m.put("erroCode", Code.ERROR2.getIndex());
			m.put("content", "");
			return m;
		}
		m.put("flag",Code.FLAG.getIndex());
		m.put("erroCode", "");
		m.put("content", "");
		return m;
	}
	

 

⑤ Xxmapper.xml in the mapping file

	<!-- submit -->
	<insert id="insert" parameterType="PDA_JWL_INTERFACE_H" >
	  insert into PDA_JWL_INTERFACE_H ( 
	  
	  ZYH,ZDRH,SWLX,SWRQ,GYSH,GYS,GSH,CKH,CK,XCKH,
	  XCK,LYR,XKWH,XKW,CGLX,CGR,KWH,KW,HH,WPH,
	  WPMC,GG,DW,SCPH,DJI,SL,JS,DJ,JE,BBM,
	  SLV,YJBM,PDLY,PH
	  
	  ) values
	  
	  (#{ZYH}, #{ZDRH}, #{SWLX},getdate(), #{GYSH},
 	   #{GYS}, #{GSH},#{CKH}, #{CK},#{XCKH}, 
 	   #{XCK},#{LYR},#{XKWH},#{XKW},#{CGLX}, 
	   #{CGR}, #{KWH},#{KW}, #{HH}, #{WPH},
	   #{WPMC}, #{GG},#{DW}, #{SCPH}, #{DJI},
	   #{SL}, #{JS},#{DJ}, #{JE}, #{BBM},
	   #{SLV},#{YJBM},#{PDLY}, #{PH})
	 
	</insert>