1

使用的技术:Spring MVC、Hibernate、MySQL DB、Windows 7、NetBeans IDE

我的创建、读取、更新操作可以正常工作,但是在尝试删除 UserAccount 和相关密码记录时出现异常:

严重:无法删除或更新父行:外键约束失败(profiler. password, CONSTRAINT FK4C641EBBCF6D23F4FOREIGN KEY ( user_id) REFERENCES user_account( user_id)) Oct 10, 2012 11:52:22 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions 严重:可以未将数据库状态与会话 org.hibernate.exception.ConstraintViolationException 同步:无法执行 JDBC 批量更新

引起:java.sql.BatchUpdateException:无法删除或更新父行:外键约束失败(profiler. password,CONSTRAINT FK4C641EBBCF6D23F4FOREIGN KEY(user_id)REFERENCES user_accountuser_id))

UserAccount & Password 关系:

在此处输入图像描述

用户帐户类:

package com.profile.beans;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

@Entity
@Table(name = "user_account")
public class UserAccount implements Serializable {

    @Autowired
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_account_seq")
    @SequenceGenerator(name = "user_account_seq", sequenceName = "user_account_seq")
    @Column(name = "user_id")
    private Long userId ;
    //
    @Autowired
    @Column(name = "user_name")
    private String userName;
    //
    @Autowired
    @Column(name = "user_type")
    private String userType;
    //
    @Autowired
    @Column(name = "first_name")
    private String firstName;
    //
    @Autowired
    @Column(name = "last_name")
    private String lastName;
    //
    @Autowired
    @Column(name = "email")
    private String email;
    //
    @Autowired
    @Column(name = "phone_contact")
    private String phoneContact; 

    //
    @Autowired
    @Column(name = "address")
    private String address;
    //
    @Autowired
    @Column(name = "city")
    private String city ; 
     //
    @Autowired
    @Column(name = "state")
    private String state; 
     //
    @Autowired
    @Column(name = "country")
    private String country;
     //
    @Autowired
    @Column(name = "zipcode")
    private Integer zipcode = 0;

    //is the user account Active either due to user deactivation,admin deactivation, or nonpayment
    @Autowired
    @Column(name = "active")
    private boolean active = false;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "UserAccount")  
    @JoinColumn(name="user_id")
    private Password Password = null; 


    @OneToMany(mappedBy="UserAccount",cascade={CascadeType.ALL})    
    @JoinColumn(name="doc_id")      
    private List<Document> documents = null; 

    @Autowired(required = false)
    public UserAccount() {
    } 


  @Autowired(required = true)
    public UserAccount(Long userId, String userName, String userType, String firstName, String lastName, String email, String phoneContact, String address, String city, String state, String country, Integer zipcode) {
        this.userId = userId;
        this.userName = userName;
        this.userType = userType;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.phoneContact = phoneContact;
        this.address = address;
        this.city = city;
        this.state = state;
        this.country = country;
        this.zipcode = zipcode;
    }

    public com.profile.beans.Password getPassword() {
        return Password;
    }

    public void setPassword(com.profile.beans.Password Password) {
        this.Password = Password;
    }
    public boolean isActive() {
        return active;
    }
    public void setActive(boolean active) {
        this.active = active;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Document> getDocuments() {
        return documents;
    }

    public void setDocuments(List<Document> documents) {
        this.documents = documents;
    }

    public Integer getZipcode() {
        return zipcode;
    }



    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }


    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPhoneContact() {
        return phoneContact;
    }

    public void setPhoneContact(String phoneContact) {
        this.phoneContact = phoneContact;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public void setZipcode(Integer zipcode) {
        try
        {
        this.zipcode = zipcode;
        }
        catch (NumberFormatException exc)
        {
            exc.printStackTrace();
        }
    }




    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserAccount other = (UserAccount) obj;
        if ((this.userId == null) ? (other.userId != null) : !this.userId.equals(other.userId)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 73 * hash + (this.userId != null ? this.userId.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "UserAccount{" + "userId=" + userId + ", userName=" + userName + ", userType=" + userType + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + ", phoneContact=" + phoneContact + ", address=" + address + ", city=" + city + ", state=" + state + ", country=" + country + ", zipcode=" + zipcode + ", active=" + active + ", documents=" + documents + '}';
    }


}

密码类:

package com.profile.beans;

import java.io.Serializable;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "Password")
public class Password implements Serializable {

    @Autowired(required = false)
    public Password() {
    }

    @Autowired(required = true)
    public Password(UserAccount UserAccount) {
       this.UserAccount = UserAccount;
    }
    @Autowired
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "password_seq")
    @SequenceGenerator(name = "password_seq", sequenceName = "password_seq")
    @Column(name = "password_id")
    private Long passwordId;
    @Autowired
    @Column(name = "password")
    private String password = null;  
     //1 to 1 relation with UserAccounts
       //1 to 1 relation with UserAccounts
    @Autowired
    @Qualifier("UserAccount")
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id", referencedColumnName="user_id",nullable = false)
    private UserAccount UserAccount;

@Autowired(required = true)
        public Password(UserAccount UserAccount, String password) {
            this.UserAccount = UserAccount;
            this.password = password;
        }

    public UserAccount getUserAccount() {
        return UserAccount;
    }

    public void setUserAccount(UserAccount UserAccount) {
        this.UserAccount = UserAccount;
    }

    public Long getPasswordId() {
        return passwordId;
    }

    public void setPasswordId(Long passwordId) {
        this.passwordId = passwordId;
    }

        public String getPassword() {
            return password;
        }
    }

我的数据库 DDL(MySQL 语法):

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

DROP SCHEMA IF EXISTS `profiler`;
CREATE SCHEMA IF NOT EXISTS `profiler` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
DROP SCHEMA IF EXISTS `profiler` ;
CREATE SCHEMA IF NOT EXISTS `profiler` DEFAULT CHARACTER SET latin1 ;
USE `profiler` ;

-- -----------------------------------------------------
-- Table `profiler`.`user_account`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`user_account` ;

CREATE  TABLE IF NOT EXISTS `profiler`.`user_account` (
  `user_id` BIGINT(20) NOT NULL ,
  `user_name` VARCHAR(45) NULL DEFAULT NULL ,
  `user_type` VARCHAR(45) NULL DEFAULT NULL ,
  `first_name` VARCHAR(45) NULL DEFAULT NULL ,
  `last_name` VARCHAR(45) NULL DEFAULT NULL ,
  `email` VARCHAR(45) NULL DEFAULT NULL ,
  `phone_contact` VARCHAR(45) NULL DEFAULT NULL ,
  `address` VARCHAR(45) NULL DEFAULT NULL ,
  `city` VARCHAR(45) NULL DEFAULT NULL ,
  `state` VARCHAR(45) NULL DEFAULT NULL ,
  `country` VARCHAR(45) NULL DEFAULT NULL ,
  `zipcode` VARCHAR(45) NULL DEFAULT NULL ,
  `active` TINYINT(1) NULL DEFAULT NULL ,
  PRIMARY KEY (`user_id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;


-- -----------------------------------------------------
-- Table `profiler`.`document`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`document` ;

CREATE  TABLE IF NOT EXISTS `profiler`.`document` (
  `doc_id` BIGINT(20) NOT NULL ,
  `title` VARCHAR(45) NULL DEFAULT NULL ,
  `format` VARCHAR(45) NULL DEFAULT NULL ,
  `url_string` VARCHAR(45) NULL DEFAULT NULL ,
  `size_in_bytes` INT(11) NULL DEFAULT NULL ,
  `created_on` TIMESTAMP NULL DEFAULT NULL ,
  `bytes` BLOB NULL DEFAULT NULL ,
  `height` INT(11) NULL DEFAULT NULL ,
  `width` INT(11) NULL DEFAULT NULL ,
  `user_id` BIGINT(20) NOT NULL ,
  PRIMARY KEY (`doc_id`) ,
  CONSTRAINT `user_id_fk`
    FOREIGN KEY (`user_id` )
    REFERENCES `profiler`.`user_account` (`user_id` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;


-- -----------------------------------------------------
-- Table `profiler`.`password`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `profiler`.`password` ;

CREATE  TABLE IF NOT EXISTS `profiler`.`password` (
`password_id` BIGINT(20) NOT NULL ,
  `password` VARCHAR(45) NOT NULL ,
`user_id` BIGINT(20) NOT NULL ,
  PRIMARY KEY (`password_id`) ,
  CONSTRAINT `user_id_fk_1`
    FOREIGN KEY (`user_id` )
    REFERENCES `profiler`.`user_account` (`user_id` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;

CREATE INDEX `user_id_fk_idx` ON `profiler`.`password` (`user_id` ASC) ;



SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SET foreign_key_checks = 1;

UserAccount 控制器类:

@Controller
@RequestMapping("/UserAccount")
public class UserAccountController {
      @Autowired
    private UserAccountDao userAccountDao;
     @Autowired
     private PasswordDao passwordDao;

    public UserAccountController() {
    }

    public UserAccountController(UserAccountDao userAccountDao, PasswordDao passwordDao) {
        this.userAccountDao = userAccountDao;
        this.passwordDao = passwordDao;
    }
@RequestMapping(value="/Register")
    public String RegisterationView()
{
    return "UserAccount/Register";
}
@RequestMapping(value="/Login")
    public String LoginView()
{
    return "UserAccount/Login";
}
@RequestMapping(value="/Update")
    public String UpdateView()
{
    return "UserAccount/Update";
}
    //create
    @RequestMapping(value="/create",method = RequestMethod.POST)
    public String create(
            @RequestParam("username") String username,
            @RequestParam("email") String email,
            @RequestParam("firstname") String firstName,
            @RequestParam("lastname") String lastName,
            @RequestParam("phonecontact") String phonecontact,
            @RequestParam("address") String address,
             @RequestParam("state") String state,
             @RequestParam("city") String city,
             @RequestParam("country") String country,
             @RequestParam("password") String password,
             @RequestParam("zipcode") Integer zipcode,
             HttpSession session,HttpServletRequest request, Model model)
    {
        String view = null ; 
        //*check if username exists
        //*if email exists

         UserAccount userAccount = new UserAccount(); 

        userAccount.setAddress(address);
        userAccount.setCity(city);
        userAccount.setCountry(country);
        userAccount.setState(state);
        userAccount.setPhoneContact(phonecontact);
        userAccount.setEmail(email);
        userAccount.setZipcode(zipcode);
        userAccount.setFirstName(firstName);
        userAccount.setLastName(lastName);
        userAccount.setUserName(username);
        userAccount.setUserType(utility.UserTypes.REGULAR);
        //instatiate password 
        //**password not exist before & must be at least characters long 

        Password userPassword = new Password(userAccount,password);
        userAccountDao.create(userAccount);
        passwordDao.create(userPassword);
        //add userAccount to model 
        model.addAttribute("userAccount", userAccount);
        session.setAttribute("userAccount", userAccount);
         view =  "UserAccount/UserMainMenu";



        return view;
    }
    //update
   @RequestMapping(value="/update",method = RequestMethod.GET)
    public String update( @RequestParam(value="username", required=false) String username,
            @RequestParam(value="email",required=false) String email,
            @RequestParam(value="firstname",required=false) String firstName,
            @RequestParam(value="lastname",required=false) String lastName,
            @RequestParam(value="phonecontact",required=false) String phonecontact,
            @RequestParam(value="address",required=false) String address,
            @RequestParam(value="state",required=false) String state,
            @RequestParam(value="city",required=false) String city,
            @RequestParam(value="country",required=false) String country,
            @RequestParam(value="zipcode",required=false) Integer zipcode,@RequestParam(value="update",required=false) String update,HttpSession session,HttpServletRequest request)
    {
         String view = null ; 
          UserAccount userAccount = (UserAccount)session.getAttribute("userAccount");
         //*check if username exists
        //*if email exists
          try
          {
              System.out.println("Class  UserAccountController, update:" + update); 
     if (update.equalsIgnoreCase("update"))
             {
        //reset values in case updated info 
        userAccount.setAddress(address);
        userAccount.setCity(city);
        userAccount.setCountry(country);
        userAccount.setState(state);
        userAccount.setPhoneContact(phonecontact);
        userAccount.setEmail(email);
        userAccount.setZipcode(zipcode);
        userAccount.setFirstName(firstName);
        userAccount.setLastName(lastName);
        userAccount.setUserName(username);
        userAccount.setUserType(utility.UserTypes.REGULAR);
        //instatiate password 
        userAccountDao.update(userAccount);
        //add userAccount to model 
        session.setAttribute("userAccount", userAccount);
        view =  "UserAccount/UserMainMenu";
             }
      if (update.equalsIgnoreCase("delete"))
             {

      System.out.println("Class  UserAccountController, userAccount: "+userAccount);
      //query for password that corresponds to particular user 
      Password password = (Password)passwordDao.getByUserAccount(userAccount);
      System.out.println("Class  UserAccountController, password: "+password );
     password.setUserAccount(null);
      //delete password 
      passwordDao.delete(password);
      //delete user account 
      userAccountDao.delete(userAccount);
      session.removeAttribute("userAccount");
      view =  "UserAccount/UserMainMenu";

             }
          }
          catch (Exception exc)
          {
              //forward to error page 
              exc.getMessage();
              view = "error";
          }
        return view;
    }
    //delete
    @RequestMapping(value="/delete",method = RequestMethod.DELETE)
    public String delete( @RequestParam("id")Long id,HttpSession session,HttpServletRequest request)
    {
        String view = null ; 
        UserAccount newUserAccount = userAccountDao.getById(id);
        userAccountDao.delete(newUserAccount);
        view =  "UserAccount/UserMainMenu";
        return view;
    }
    //read
    @RequestMapping(value="/read",method = RequestMethod.GET)
    public void read(Long id)
    {
        userAccountDao.getById(id);
    }

    public UserAccountDao getUserAccountDao() {
        return userAccountDao;
    }

    public void setUserAccountDao(UserAccountDao userAccountDao) {
        this.userAccountDao = userAccountDao;
    }

    public PasswordDao getPasswordDaoImpl() {
        return passwordDao;
    }

    public void setPasswordDaoImpl(PasswordDaoImpl passwordDao) {
        this.passwordDao = passwordDao;
    }

}

PasswordDaoImpl 类:

@Repository
@Transactional
public class PasswordDaoImpl implements PasswordDao{
   @Autowired
    private SessionFactory sessionFactory;

    private Session currentSession()
    {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public Password getByUserAccount(UserAccount UserAccount) { 
    String hql = "FROM com.profile.beans.Password WHERE Password.UserAccount.UserId =:id";
    Long id = UserAccount.getUserId();
    Query q = currentSession().createQuery(hql);
    return (Password)q.setParameter("id",id).list().get(0);
    }

    @Override
    public void create(Password Password) {
        currentSession().save(Password);
    }

    @Override
    public void delete(Password Password) {
        currentSession().delete(Password);
    }

    @Override
    public void update(Password Password) {
        currentSession().update(Password);
    }
       public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

}
4

1 回答 1

0

您应该在删除 UserAccount 之前中断关系:

Password pass = userAccount.getPassword();
userAccount.setPassword(null);
userAccountDao.delete(pass);
userAccountDao.delete(userAccount);
于 2012-10-10T19:43:15.517 回答