Hibernate与JPA注释问题 - 懒惰对象

时间:2011-02-23 15:00:28

标签: java hibernate orm

我有一个与许多其他表关联的USER表,通常是星形拓扑。

像这样:

@Entity
@Table(name = "user")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "user_USERID_GENERATOR", sequenceName = "user_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "userR_USERID_GENERATOR")
    @Column(name = "user_id")
    private long userId;

    @Basic
    @Column(name = "password_hex")
    private String password;

    @Basic
    @Column(name = "language")
    private String language;

    @Temporal(TemporalType.DATE)
    private Date created;

    @Temporal(TemporalType.DATE)
    private Date modyfied;

    @Basic
    @Column(name = "first_name")
    private String firstName;

    @Basic
    @Column(name = "last_name")
    private String lastName;

    @Basic
    @Column(name = "passport")
    private String passport;

    @Basic
    @Column(name = "pesel")
    private String pesel;

    @Basic
    @Column(name = "phone_nr1")
    private String phoneNr1;

    @Basic
    @Column(name = "phone_nr2")
    private String phoneNr2;

    @Column(name = "hash")
    private String hash;


    // uni-directional many-to-one association to DictUserType
    @ManyToOne
    @JoinColumn(name = "status")
    private DictUserStatus status;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = { CascadeType.ALL })
    private Set<Email> emails = new HashSet<Email>(0);

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = { CascadeType.ALL })
    private Set<Address> address = new HashSet<Address>(0);

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = { CascadeType.ALL })
    private Set<ArchivePasswords> archivePasswords = new HashSet<ArchivePasswords>(
            0);

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = { CascadeType.ALL })
    private Set<HostsWhitelist> hostsWhitelist = new HashSet<HostsWhitelist>(0);

.... 我有一个DAO层,即按用户ID搜索的方法。

public User findUser(long userId) throws UserNotFoundException {
    User user = userDao.findUser(userId);
    if (user == null) {
        throw new UserNotFoundException("Could not find user with id = "
                + userId);
    }

    return user;
}

为什么延迟抓取不起作用?

3 个答案:

答案 0 :(得分:0)

您应该发布您正在接收的堆栈跟踪。 LazyLoadingException在哪里发生?在用户对象?您是否尝试从另一个对象访问它?

这是臭名昭着的LazyInitializationException吗?如果是这样,那么你需要在服务中手动遍历Object图形(假设您的DAO代码片段实际上是一个Service方法而不是DAO本身),或者研究OpenSessionInViewFilter(假设您使用的是Spring)。

答案 1 :(得分:0)

如果您想通过电子邮件获取用户。

    @Transactional
    public List getUserWithEmails(long userId){
        User user = userDao.findUser(userId);
        if (user == null) {
            throw new UserNotFoundException("Could not find user with id = "
                    + userId);
        }
        for(Email email:user.getEmails()){
            email.getId();
        }
        return user;
    }

同样的程序适用于其他一对多集合。就像其他人所说,你需要在web.xml中添加OpenSessionInView(Hibernate)过滤器或OpenEntityManagerInView(JPA)过滤器

答案 2 :(得分:0)

如果未指定,懒惰的fet hing将不会默认为EAGER。

public @interface Basic 最简单的映射到数据库列的类型。 Basic注释可以应用于以下任何类型的持久属性或实例变量:Java原始类型,基本类型的包装,String,java.math.BigInteger,java.math.BigDecimal,java.util.Date, java.util.Calendar,java.sql.Date,java.sql.Time,java.sql.Timestamp,byte [],Byte [],char [],Character [],枚举以及任何其他实现java的类型。 io.Serializable。

对于这些类型的持久字段和属性,Basic注释的使用是可选的。如果没有为此类字段或属性指定基本注释,则将应用基本注释的默认值。

  Example 1:

    @Basic
    protected String name;

    Example 2:

    @Basic(fetch=LAZY)
    protected String getName() { return name; }

public abstract FetchType fetch

(可选)定义字段或属性的值是应该延迟加载还是必须急切获取。 EAGER策略是持久性提供程序运行时的要求,必须急切地获取该值。 LAZY策略是对持久性提供程序运行时的提示。如果未指定,默认为EAGER。

Default:
javax.persistence.FetchType.EAGER
optional

public abstract boolean optional

(可选)定义字段或属性的值是否为null。这是一个提示,被忽略了原始类型;它可以用于模式生成。如果未指定,则默认为true。 默认: 真