У меня есть два класса:Круговые реверансы в Ibatis
class Apple {
Worm worm;
}
class Worm {
Apple apple;
}
Они хранятся в БД в 1: 1 моды:
table Apple(id, wormId)
table Worm(id)
Каждое яблоко имеет только один червь, и наоборот.
с из Ibatis я могу сделать это просто:
Worm worm = new Worm();
Apple apple = new Apple();
worm.setApple(apple);
apple.setWorm(worm);
Как я могу это сделать в Ibatis?
<resultMap id="Apple" type="Apple">
<result property="id" column="id"/>
<result property="worm" column="id" select="getWormByApple"/>
</resultMap>
<resultMap id="Worm" type="Worm">
<result property="id" column="id"/>
<result property="apple" column="id" select="getAppleByWorm"/>
</resultMap>
<select id="getApple" resultMap="Apple" parameterClass="java.lang.Long">
SELECT * FROM Apples where id=#value#
</select>
<select id="getWormByApple" resultMap="Worm" parameterClass="java.lang.Long">
SELECT * FROM Worms where appleId=#value#
</select>
Итак, я хочу, чтобы быть в состоянии сделать:
Apple apple = foo.queryForObject("getApple", 42L);
Worm = worm.getApple();
Apple appleAgain = apple.getWorm().getApple();
// apple == appleAgain here
Вместо этого я получаю StackOverflowException потому, что распорки называет getWormByApple/getApple навсегда.
Я вижу только одно решение здесь:
class Apple {
void setWorm(Worm worm){
this.worm = worm;
worm.setApple(this);
}
... и удалить "свойство =" яблоко "" от Worm resultMap.
Но это отстой, потому что я должен был бы помнить, какие сеттеры обновляют аргумент, а с нет. Это также плохо, потому что может привести к бесконечному циклу, если сеттер Worm изменит аргумент.
Я также не хочу «исправлять» утечки iBatis с помощью моих классов моделей (т. Е. Я вообще не хочу прикасаться к моей модели).
Было бы неплохо иметь какой-то «постпроцессор»:
<resultMap id="Apple" type="Apple">
<result property="id" column="id"/>
<result property="worm" select="getWormByApple"/>
<result property="worm.apple" postProcessor="appleToWormSetter"/>
</resultMap>
но нет какой-либо в Ibatis.
Как его решить? Thanks