Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mybatis反向关系导致对象重复_Java_Xml_Mybatis_Ibatis_Relation - Fatal编程技术网

Java Mybatis反向关系导致对象重复

Java Mybatis反向关系导致对象重复,java,xml,mybatis,ibatis,relation,Java,Xml,Mybatis,Ibatis,Relation,我试图用MyBatis 3.2.8映射集合的反向关系。似乎MyBatis复制对象,即使它们具有相同的id public class ObjA { private String id; private ArrayList<ObjB> objBs; // Getters, setters ... // Equals based on the id field } public class ObjB { private String id;

我试图用MyBatis 3.2.8映射集合的反向关系。似乎MyBatis复制对象,即使它们具有相同的id

public class ObjA {
    private String id;
    private ArrayList<ObjB> objBs;

    // Getters, setters ...

    // Equals based on the id field
}

public class ObjB {
    private String id;
    private ObjA objA;

    // Getters, setters ...

    // Equals based on the id field
}
映射xml文件

<resultMap id="xx" type="ObjA">
    <id column="idA" property="id" />
    <collection property="objBs" javaType="ArrayList" ofType="ObjB">
        <id column="idB" property="id"/>
        <association property="objA" type="ObjA">
            <id column="idA" property="id" />
        </association>
    </collection>
</resultMap>
JUnit测试

ArrayList<ObjA> result = service.getAllObjA();

for(ObjA objA : result) {
    for(ObjB objB : objA.getObjBs()) {
        assertEquals(objB.getObjA(), objA); // Pass
        assertTrue(objB.getObjA() == objA); // Does not pass
    }
}
我希望objB.getObjA和objA是objA的相同引用

如何配置结果映射以使其正常工作。

您描述的POJO的ObjA和ObjB是循环依赖的

考虑以下示例:让我们有一个艺术家类和一个录音类。他们不需要实现可比较的接口,但我们这样做是因为我们想对这些对象进行排序。或者,可以编写SQL查询来指定所返回行的所需排序顺序

这是艺术课。请注意,艺术家持有其录音集

import java.util.List;

public class Artist implements Comparable {

  private int id;
  private List<Recording> recordings;
  private String name;

  public Artist() {}
  public Artist(String name) { this.name = name; }

  public int compareTo(Object obj) {
    Artist r = (Artist) obj;
    return name.compareTo(r.name);
  }

  public int getId() { return id; }
  public void setId(int id) { this.id = id; }

  public String getName() { return name; }
  public void setName(String name) {
    this.name = name;
  }

  public List<Recording> getRecordings() { return recordings; }
  public void setRecordings(List<Recording> recordings) {
    this.recordings = recordings;
  }
}
配置:

映射语句在从SqlMapConfig.XML文件引用的XML文件中定义

这是一个文件,它指定了与我们的艺术家表相关的语句

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
  "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Artist">

  <delete id="deleteAll">
    delete from artists
  </delete>

  <insert id="insert" parameterClass="com.ociweb.music.Artist">
    insert into artists (name) values (#name#)
    <selectKey resultClass="int" keyProperty="id">
      select last_insert_id() as id
    </selectKey>
  </insert>

  <resultMap id="result" class="com.ociweb.music.Artist">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- This results in N+1 selects. To avoid this, see page 40
         in the iBATIS Developer Guide. -->
    <result property="recordings" column="id"
      select="Recording.getByArtist"/>
  </resultMap>

  <select id="getById"
    parameterClass="java.lang.Integer" resultMap="result">
    select * from artists where id=#id#
  </select>

  <select id="getAll" resultClass="com.ociweb.music.Artist">
    select * from artists
  </select>

</sqlMap>
下面是一个文件,它指定了与recordings表相关的语句

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
  "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Recording">

  <delete id="deleteAll">
    delete from recordings
  </delete>

  <insert id="insert" parameterClass="com.ociweb.music.Recording">
    insert into recordings (name, year, artist_id)
    values (#name#, #year#, #artist.id#)
    <selectKey resultClass="int" keyProperty="id">
      select last_insert_id() as id
    </selectKey>
  </insert>

  <resultMap id="resultWithoutArtist" class="com.ociweb.music.Recording">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="year" column="year"/>
  </resultMap>

  <resultMap id="result"
    class="com.ociweb.music.Recording" extends="resultWithoutArtist">
    <result property="artist" column="artist_id" select="Artist.getById"/>
  </resultMap>

  <select id="getAll" resultClass="com.ociweb.music.Recording">
    select * from recordings
  </select>

  <!-- resultWithoutArtist is used here to avoid a circular
       dependency when Artist.result (in Artist.xml) is used. -->
  <select id="getByArtist"
    parameterClass="java.lang.Integer" resultMap="resultWithoutArtist">
    select * from recordings where artist_id=#artistId#
  </select>

  <select id="getByYear"
    parameterClass="java.lang.Integer" resultMap="result">
    select * from recordings where year=#year#
  </select>

</sqlMap>

尝试下面的配置和映射,因为非常感谢您的解释非常好的答案!不幸的是,这个解决方案给我带来了一个复杂性问题。我终于找到了一个漫游环境。@Sacha不客气:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
  "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Artist">

  <delete id="deleteAll">
    delete from artists
  </delete>

  <insert id="insert" parameterClass="com.ociweb.music.Artist">
    insert into artists (name) values (#name#)
    <selectKey resultClass="int" keyProperty="id">
      select last_insert_id() as id
    </selectKey>
  </insert>

  <resultMap id="result" class="com.ociweb.music.Artist">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- This results in N+1 selects. To avoid this, see page 40
         in the iBATIS Developer Guide. -->
    <result property="recordings" column="id"
      select="Recording.getByArtist"/>
  </resultMap>

  <select id="getById"
    parameterClass="java.lang.Integer" resultMap="result">
    select * from artists where id=#id#
  </select>

  <select id="getAll" resultClass="com.ociweb.music.Artist">
    select * from artists
  </select>

</sqlMap>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
  PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
  "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Recording">

  <delete id="deleteAll">
    delete from recordings
  </delete>

  <insert id="insert" parameterClass="com.ociweb.music.Recording">
    insert into recordings (name, year, artist_id)
    values (#name#, #year#, #artist.id#)
    <selectKey resultClass="int" keyProperty="id">
      select last_insert_id() as id
    </selectKey>
  </insert>

  <resultMap id="resultWithoutArtist" class="com.ociweb.music.Recording">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="year" column="year"/>
  </resultMap>

  <resultMap id="result"
    class="com.ociweb.music.Recording" extends="resultWithoutArtist">
    <result property="artist" column="artist_id" select="Artist.getById"/>
  </resultMap>

  <select id="getAll" resultClass="com.ociweb.music.Recording">
    select * from recordings
  </select>

  <!-- resultWithoutArtist is used here to avoid a circular
       dependency when Artist.result (in Artist.xml) is used. -->
  <select id="getByArtist"
    parameterClass="java.lang.Integer" resultMap="resultWithoutArtist">
    select * from recordings where artist_id=#artistId#
  </select>

  <select id="getByYear"
    parameterClass="java.lang.Integer" resultMap="result">
    select * from recordings where year=#year#
  </select>

</sqlMap>