2011-02-23 105 views
1

我有一個USER表與許多其他表,通常,星型拓撲關聯。休眠與JPA註釋問題 - 懶惰的對象

像這樣:

@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; 
} 

爲什麼懶取指不起作用?

+1

你會得到什麼例外?你遇到異常時你想做什麼? – jny 2011-02-23 15:06:53

+0

你可以發佈相關的代碼和例外嗎? – jny 2011-02-23 15:57:58

回答

0

您應該發佈您收到的堆棧跟蹤。 LazyLoadingException發生在哪裏?在用戶對象?你是否試圖從另一個對象訪問它?

這是臭名昭着的LazyInitializationException?如果是這樣,那麼你需要在服務中手動遍歷對象圖(假設你的DAO代碼片段實際上是一個Service方法而不是DAO本身),或者研究OpenSessionInViewFilter(假設你使用的是Spring)。

+0

我有一個空的用戶對象(沒有ID)沒有地址,電子郵件等......當我在我的服務層執行findUser(long userId)時,我得到了具有所有集合的User對象。我只想得到User對象。 ?? – user6778654 2011-02-24 16:42:37

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)過濾器。

+0

你能舉個例子嗎? – user6778654 2011-02-24 16:44:39

0

如果未指定,則不會執行惰性缺省值到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 

(可選)定義的字段或屬性的值是否可以爲空。這是一種暗示,對原始類型不予考慮;它可能用於模式生成。如果未指定,則默認爲true。 默認: true