mybatis / mybatipse

Eclipse plugin adding support for MyBatis SQL Mapper Framework.
Eclipse Public License 1.0
333 stars 91 forks source link

Error "Property xxx not found in class yyy" on many properties, where the property exists in the class #100

Closed peter-urbanus closed 2 years ago

peter-urbanus commented 4 years ago

For instance, these properties were al marked with error:

  <resultMap id="programCall" type="nl.mediacenter.xref.dal.ProgramCall">
    <result property="calledProgram"      column="CALLED_PROGRAM"      jdbcType="CHAR"/>
    <result property="calledProgramType"  column="CALLED_PROGRAMTYPE"  jdbcType="CHAR"/>
    <result property="calledProgramText"  column="CALLED_PROGRAMTEXT"  jdbcType="CHAR"/>
    <result property="callingProgram"     column="CALLING_PROGRAM"     jdbcType="CHAR"/>
    <result property="callingProgramType" column="CALLING_PROGRAMTYPE" jdbcType="CHAR"/>
    <result property="callingProgramText" column="CALLING_PROGRAMTEXT" jdbcType="CHAR"/>
  </resultMap>

And this is part of the class in question

package nl.mediacenter.xref.dal;

public class ProgramCall
{
public String calledProgram;
private String calledProgramType;
private String calledProgramText;
private String callingProgram;
private String callingProgramType;
private String callingProgramText;
public String getCalledProgram()
{
    return calledProgram;
}
public String getCalledProgramType()
{
    return calledProgramType;
}
public String getCalledProgramText()
{
    return calledProgramText;
}

As you can see, all the properties are there. The errors went away after I uninstalled MyBatipse.

harawata commented 4 years ago

Thank you for the report, @peter-urbanus !

A few quick things that might fix the problem:

If none of them didn't resolve the issue, please try the followings and let me know the results:

  1. Do the other features like auto-completion work?
  2. When you import the jpetstore project, do you get the similar validation errors?
purbanus commented 2 years ago

Hi @Hirawate, sorry for taking so long to respond. I recently installed MyBatipse and I have the same problem. I tried all your suggestions with no result. I also imported the jpetstore project, and it didn't have any errors. However, this may be because jpetstore doesn't use any <resultMap>. I do have some news though: I have the errors in a handwritten mapper.xml file, but in xml generated by MyBatis Generator, which uses <resultMap>, there are no errors!. Both mappers are in the same project.

Again as previously, the errors went away after I uninstalled MyBatipse

purbanus commented 2 years ago

You can ask me anything :-)

purbanus commented 2 years ago

Here is the XML of the mapper that has the errors:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pu.heavymetal.dal.queries.QueriesMapper">
  <resultMap id="jaarDocument" type="pu.heavymetal.bo.JaarDocument">
    <result property="jaar"      column="JAAR"    jdbcType="INTEGER"/>
    <result property="issues"    column="ISSUES"  jdbcType="INTEGER"/>
  </resultMap>

Here, both properties can't be found with a message like this: Property 'jaar' not found in class pu.heavymetal.bo.JaarDocument. Here is the generated XML that has no errors:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pu.heavymetal.dal.generated.AuteurDalMapper">
  <resultMap id="BaseResultMap" type="pu.heavymetal.dal.generated.AuteurDal">
     <id column="id" jdbcType="INTEGER" property="id" />
    <result column="naam" jdbcType="VARCHAR" property="naam" />
  </resultMap>

Do you want me to show the java code?

harawata commented 2 years ago

Thanks for the info @purbanus ,

Try copying the BaseResultMap in the OK mapper and paste it into the NG mapper (i.e. QueriesMapper) and see if MyBatipse reports the error or not.

purbanus commented 2 years ago

Ok, I did that, and it gives no errors! Here is the XML:

<mapper namespace="pu.heavymetal.dal.queries.QueriesMapper">
 <resultMap id="BaseResultMap" type="pu.heavymetal.dal.generated.AuteurDal">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="naam" jdbcType="VARCHAR" property="naam" />
  </resultMap>
  <resultMap id="jaarDocument" type="pu.heavymetal.bo.JaarDocument">
    <result property="jaar"      column="JAAR"    jdbcType="INTEGER"/>
    <result property="issues"    column="ISSUES"  jdbcType="INTEGER"/>
  </resultMap>

So the BaseResultMap has no errors, the jaarDocument has two. I still have no idea.

harawata commented 2 years ago

One step closer. :) Now we know that the difference lies between those two classes.

It is worth checking the directory structure in Finder/File Explorer. It should look like this:

image

But sometimes, users create a directory (i.e. package) that contains a dot.

image

It could be something else, but compare these classes carefully and you'll find the answer.

purbanus commented 2 years ago

I'm afraid not. Here is a screenshot of the directory structure Screenshot from 2021-12-04 02-00-58

harawata commented 2 years ago

It's Eclipse, right? Did you check it in the system's file explorer?

purbanus commented 2 years ago

This is indeed Eclipse. Here is the same screenshot of the file system: Screenshot from 2021-12-04 02-17-49

harawata commented 2 years ago

Well, could you post the content of JaarDocument.java?

purbanus commented 2 years ago

Sure, there you go

package pu.heavymetal.bo;

public class JaarDocument
{
private final int jaar;
private final long issues;
public JaarDocument( Integer aJaar, Long aIssues )
{
    super();
    jaar = aJaar;
    issues = aIssues;
}
public int getJaar()
{
    return jaar;
}
public long getIssues()
{
    return issues;
}

}

Oh, now I see: it's the final in the member definitions. If I remove that the errors go away!

harawata commented 2 years ago

In that case, you need to use 'constructor mapping'.

<resultMap id="jaarDocument" type="pu.heavymetal.bo.JaarDocument">
  <constructor>
    <arg column="JAAR" javaType="java.lang.Integer" />
    <arg column="ISSUES" javaType="java.lang.Long" />
  </constructor>
</resultMap>

The types of constructor args should match the field types, BTW.

Please see the doc for the details. https://mybatis.org/mybatis-3/sqlmap-xml.html#constructor

purbanus commented 2 years ago

That seems to solve the problem. However, MyBatis has no problem using the immutable class, it's only MyBatipse that has a problem with that. If I uninstall MyBatipse everything runs fine, and there aren't any errors in the XML.

harawata commented 2 years ago

MyBatis sets values to final fields using reflection, but you really should not rely on that 'feature' as JDK gets stricter.

purbanus commented 2 years ago

Ok, I will accept your answer as the final answer, so you can close the problem. Thanks a lot for your time!

harawata commented 2 years ago

Thank you for taking the time to report the issue! 👍