2013-07-24 116 views
3

我有兩個實體作爲用戶和項目之間有@ManyToMany關係,如下所示。休眠更新子實體時更新父實體

實體類

import org.hibernate.annotations.Cascade; 
import org.hibernate.annotations.CascadeType; 

@Entity 
@Table(name = "users") 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column (name = "id") 
    private int id; 
    @Column (name = "email") 
    private String email; 
    @Column (name = "password") 
     private String password; 
    @Column (name = "last_login") 
    private Date lastLogInDate; 
    @ManyToMany(fetch = FetchType.EAGER) 
     @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) 
     @JoinTable(name = "project_assigned", joinColumns = { @JoinColumn(name = "fk_user_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_project_id") }) 
    private Set<Projects> projects = new HashSet<Projects>(0); 

    // setter and getter methods. 
} 

@Entity 
@Table(name = "projects") 
public class Projects { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id") 
    private int id; 
    @Column (name = "name") 
    private String name;  
    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(name = "user_projects", joinColumns = { @JoinColumn(name = "fk_project_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_user_id") }) 
    private Set<User> userSet = new HashSet<User>(0); 

} 

DAO類

@Repository 
public class UserDAO { 

    public User findByCredentials(String email, String password) { 
     String queryString = " from User u where u.email = ? and u.password = ?"; 
     Query query = sessionFactory.getCurrentSession().createQuery(queryString); 
     query.setString(0, email); 
     query.setString(1, password);  
     return (User) query.uniqueResult();  
    } 

    public boolean updateUser(User user) { 
     boolean result = true; 
     Session session = null; 
     try { 
      session = sessionFactory.getCurrentSession(); 
      session.update(user); 
     } catch (HibernateException e) { 
      result = false; 
      logger.error("Can not Update User"+e); 
      e.printStackTrace(); 
     } 
     return result; 
    }   
} 

服務類

@Service 
@Transactional(readOnly = true,propagation=Propagation.SUPPORTS) 
public class UserService { 

    @Autowired 
    private UserDAO userDAO; 

    public User findByCredentials(String userName, String lastName) { 
     return userDAO.findByCredentials(userName, lastName); 
    } 

    @Transactional(readOnly = false,propagation=Propagation.REQUIRED) 
    public boolean updateUser(User user) { 
     return userDAO.updateUser(user); 
    } 
} 

其他代碼

User user = userService.findByCredentials("[email protected]", "abc"); 
user.setLastLogInDate(new Date()); 
userService.updateUser(user); 

我的問題是,當我正在更新的用戶 然後分配給該用戶的所有項目實體都得到了更新(不需要火UPDATE語句) 的「LastLogInDate」因爲這是我的應用程序性能低下。我怎麼解決這個問題。我怎樣才能以更好的方式做到這一點。謝謝你的幫助。

這裏是我的SQL日誌

DEBUG org.hibernate.SQL#log - update users set email=?, password=?, last_login=? where id=? 
DEBUG org.hibernate.SQL#log - update user_projects set name=? where id=? 
DEBUG org.hibernate.SQL#log - update user_projects set name=? where id=? 
DEBUG org.hibernate.SQL#log - update user_projects set name=? where id=? 
DEBUG org.hibernate.SQL#log - update user_projects set name=? where id=? 
DEBUG org.hibernate.SQL#log - update user_projects set name=? where id=? 

回答

2

您必須設置您的級聯,因爲級聯不能在運行過程中設置(保存):

@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) 

必須至少刪除CascadeType.MERGE。因爲MERGE意味着複雜的東西接近「保存」,但更像是「將此分離的實體重新置於受管狀態並保存其狀態更改」。級聯意味着所有關聯的實體都以相同的方式被推回,並且從.merge()返回的被管理實體處理具有與其關聯的所有管理實體。

+0

感謝您的回覆我已變化根據您的建議,我已將** @ Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})**更改爲** @ Casc ade({CascadeType.SAVE_UPDATE})**但它不起作用 –

-1

刪除所有級聯選項。這將解決您的問題

1個解決方案:

解決方案1:

用戶等級:

@ManyToMany(fetch = FetchType.EAGER) 
@JoinTable(name = "user_projects", joinColumns = { @JoinColumn(name = "fk_project_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_user_id") }) 
private Set<Projects> projects; 

項目類

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "user_projects", joinColumns = { @JoinColumn(name = "fk_project_id") }, inverseJoinColumns = { @JoinColumn(name = "fk_user_id") }) 
private Set<User> userSet; 
+0

這應該作爲評論發佈,而不是作爲答案。請刪除。 – Thom