JPA的@Access批注,其值定义在AccessType枚举类中,包括AccessType.FIELD及AccessType.PROPERTY,这两个类型定义了实体的访问模式(Access mode)。
JPA注解有两种方式来指定持久化实体状态:
1.字段访问,类似于
@Column(length = 20, nullable = false)
private String userName;
通过字段来获取或设置实体的状态,getter和setter方法可能存在或不存在。这样JPA默认的访问类型为AccessType.FIELD
2.属性访问,类似于
@Column(length = 20, nullable = false)
public String getUserName()
{
return userName;
}
持久化属性必须有getter和setter方法,属性的类型由getter方法的返回类型决定,同时必须与传递到setter方法的单个参数的类型相同。这样JPA默认的访问类型为AccessType.PROPERTY
当持久化实体通过字段访问(即注解到字段上)时,JPA只关注字段而不关注getter和setter方法,即使有另外的getter和setter方法,也不会去关注。这样JPA默认该实体访问类型是AccessType.FIELD类型,这个类型是最高级别,即使在实体上增加注解@Access(AccessType.PROPERTY)也不会起作用。
当持久化实体通过属性访问(即注解到getter方法上)时,JPA只关注getter和setter方法而不关注字段,即使写有其他的字段(没有写getter和setter方法),也不会去关注。这样JPA默认该实体访问类型是AccessType.PROPERTY类型,这个类型是最高级别,即使在实体上增加注解@Access(AccessType.FIELD)也不会起作用。
到这里,似乎@Access注解没起到什么作用,实际上,在通常应用中还会有第三种方式,即混合访问(不常用)。
3.混合访问,实现混合访问模式,必须达到三个条件:
(1)在实体上显式的标记类的访问模式,通过@Access注解进行显式的指定。(否则在字段和属性上都进行了注解,JPA不知道访问哪个模式有效)
(2)在其他(正常注解之外的)字段或属性上通过@Access注解与类级别相反的访问模式。
(3)在其他(正常注解之外的)属性或者字段(第二步的注解写在字段上,此处则指属性,相反亦然)上注解@Transient(临时的)。(使其不会被正常的访问模式持久化)
类似于:
package org.eleazar.entity;
import java.io.Serializable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
/**
* 预期:数据库表中有三个字段,分别是id(主键),userName,password(30个长度)
* 实际:数据库表中有三个字段,分别是id(主键),userName,password(30个长度)
*/
@Entity
@Access(AccessType.FIELD)
public class UserInfo8 implements Serializable
{
/**
* 注释内容
*/
private static final long serialVersionUID = 8694447074089053604L;
@Id
private Integer id;
private String userName;
@Transient
private String password;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Access(AccessType.PROPERTY)
@Column(length = 30)
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
或者
package org.eleazar.entity;
import java.io.Serializable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
/**
* 预期:数据库表中有三个字段,分别是id(主键),userName,password(30个长度)
* 实际:数据库表中有两个字段,分别是id(主键),userName,password(30个长度)
*/
@Entity
@Access(AccessType.PROPERTY)
public class UserInfo9 implements Serializable
{
/**
* 注释内容
*/
private static final long serialVersionUID = -6399694572685454317L;
@Id
@Access(AccessType.FIELD)
private Integer id;
private String userName;
@Access(AccessType.FIELD)
@Column(length = 30)
private String password;
@Transient
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Transient
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
即可实现混合访问模式。
参考资料:
http://www.aiuxian.com/article/p-187485.html
http://blog.163.com/sir_876/blog/static/11705223201221894424385/
Pro.JPA2中文版:精通Java持久化API
测试实例
http://download.csdn.net/detail/u012493207/9456135