如何让MyBatis使用防御性副本?

时间:2012-03-30 16:26:01

标签: java mybatis defensive-copy

让我们假设这个简单的架构:

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)); 

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>

这是我的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);
    }
} 

所以一切都非常简单,除了我在用户bean实现中从角色列表中获取防御性副本。问题是MyBatis似乎根本不支持这个,结果角色列表将为空。如果我不采用这些副本,它可以顺利运行,但设计很差。有办法解决这个问题吗?

0 个答案:

没有答案