Let's assume this simple schema:
create table User (
identity BIGINT UNSIGNED, PRIMARY KEY (identity),
name VARCHAR(32) NOT NULL);
create table Role (
identity BIGINT UNSIGNED, PRIMARY KEY (identity),
name VARCHAR(32) NOT NULL);
create table UserRole (
user_identity BIGINT UNSIGNED REFERENCES User (identity),
role_identity BIGINT UNSIGNED REFERENCES Role (identity),
PRIMARY KEY(user_identity, role_identity));
And this mapping in MyBatis:
<select id="SelectUserById" parameterType="long" resultMap="UserResultMap">
select
u.identity as u_identity,
u.name as u_name,
r.identity as r_identity,
r.name as r_name
from
User u
inner join UserRole ur on ur.user_identity = u.identity
inner join Role r on ur.role_identity = r.identity
where
u.identity = #{id}
</select>
<resultMap id="UserResultMap" type="User">
<id property="identity" column="u_identity" />
<result property="name" column="u_name" />
<collection property="roles" column="u_identity" ofType="Role" javaType="ArrayList">
<id property="identity" column="r_identity" />
<result property="name" column="r_name" />
</collection>
</resultMap>
Here's the implementation of my User bean:
public class User {
private Long identity;
private String name;
private List<Role> roles = new ArrayList<Role>();
public Long getIdentity() {
return identity;
}
public void setIdentity(Long identity) {
this.identity = identity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Role> getRoles() {
return new ArrayList<Role>(roles);
}
public void setRoles(List<Role> roles) {
this.roles = new ArrayList<Role>(roles);
}
}
So everything is pretty straightforward except for the fact that I take defensive copies from the role list in my user bean implementation. The problem is that MyBatis does not seem to support this at all and the resulting role list will be empty. If I don't take these copies it works smoothly but would be poor design. Is there a way around this?