【问题标题】:Data truncation: Data to long for column数据截断:数据长列
【发布时间】:2015-03-09 02:49:20
【问题描述】:

我正在尝试将加密密码插入到用户配置文件表中。

我创建表的sql文件是这样的:

-- ---------- Table for validation queries from the connection pool. ----------
DROP TABLE PingTable;
CREATE TABLE PingTable (foo CHAR(1));
-- ------------------------------ UserProfile ----------------------------------
DROP TABLE UserProfile;
CREATE TABLE UserProfile (
    usrId BIGINT NOT NULL AUTO_INCREMENT,
    loginName VARCHAR(30) COLLATE latin1_bin NOT NULL,
    enPassword VARCHAR(150) NOT NULL, 
    firstName VARCHAR(30) NOT NULL,
    lastName VARCHAR(40) NOT NULL,
    email VARCHAR(60) NOT NULL,
    CONSTRAINT UserProfile_PK PRIMARY KEY (usrId),
    CONSTRAINT LoginNameUniqueKey UNIQUE (loginName))
    ENGINE = InnoDB;

CREATE INDEX UserProfileIndexByLoginName ON UserProfile (loginName);

我注册用户的实现:

private String doEncryptedPassword(String clearPassword) {
    HashFunction hf = Hashing.sha512();
    HashCode hc = hf.newHasher(clearPassword.length()).putString(clearPassword, StandardCharsets.UTF_8).hash();
    return hc.toString();
}

public UserProfile registerUser(String loginName, String clearPassword,
        UserProfileDetails userProfileDetails)
        throws DuplicateInstanceException {

    try {
        userProfileDao.findByLoginName(loginName);
        throw new DuplicateInstanceException(loginName,
                UserProfile.class.getName());
    } catch (InstanceNotFoundException e) {
        String encryptedPassword = doEncryptedPassword(clearPassword);

        UserProfile userProfile = new UserProfile(loginName,
                encryptedPassword, userProfileDetails.getFirstName(),
                userProfileDetails.getLastName(), userProfileDetails
                    .getEmail());


        userProfileDao.save(userProfile);
        return userProfile;
    }

}

UserProfile.java:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

@Entity
public class UserProfile {

    private Long userProfileId;
    private String loginName;
    private String encryptedPassword;
    private String firstName;
    private String lastName;
    private String email;

    public UserProfile() {
    }

    public UserProfile(String loginName, String encryptedPassword,
            String firstName, String lastName, String email) {

        /**
         * NOTE: "userProfileId" *must* be left as "null" since its value is
         * automatically generated.
         */

        this.loginName = loginName;
        this.encryptedPassword = encryptedPassword;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    @Column(name = "usrId")
    @SequenceGenerator( // It only takes effect for
    name = "UserProfileIdGenerator", // databases providing identifier
    sequenceName = "UserProfileSeq")
    // generators.
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "UserProfileIdGenerator")
    public Long getUserProfileId() {
        return userProfileId;
    }
    public void setUserProfileId(Long userProfileId) {
        this.userProfileId = userProfileId;
    }

    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    @Column(name = "enPassword")
    public String getEncryptedPassword() {
        return encryptedPassword;
    }
    public void setEncryptedPassword(String encryptedPassword) {
        this.encryptedPassword = encryptedPassword;
    }

    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 getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "UserProfile [userProfileId=" + userProfileId + ", loginName="
                + loginName + ", encryptedPassword=" + encryptedPassword
                + ", firstName=" + firstName + ", lastName=" + lastName
                    + ", email=" + email + "]";
    }

}

消息错误:

数据截断:第 1 行的“enPassword”列的数据太长; SQL [不适用];嵌套异常是 org.hibernate.exception.DataException:数据截断:第 1 行的列“enPassword”的数据太长

我该如何解决这个问题?

doEncryptedPassword方法返回的字符串长度为129个字符)

【问题讨论】:

    标签: java mysql hibernate encryption


    【解决方案1】:

    当为列 enPassword 传递的值大于 150 个字符时,将发生此异常。尝试增加enPassword 列大小

    还要检查方法doEncryptedPassword中返回的字符串长度是多少

    【讨论】:

    • 如果可能,尝试打印传递给数据库执行的命令。
    【解决方案2】:

    我发现了问题。

    我有两个数据库 Data 和 DataTest。在“数据”中一切正常。

    在“DataTest”(用于执行测试的数据库)中,之前有这个“UserProfile”,带有多个外键(为什么不删除)。

    旧表有 enPassword 列 定义类似

    enPassword VARCHAR(30) NOT NULL
    

    这就是错误的原因(129个字符的字符串不能存储到一个大小为30的列中)。

    要解决删除带有外键的表的问题,请这样做

    SET FOREIGN_KEY_CHECKS=0;
    DROP TABLE IF EXISTS UserProfile;
    SET FOREIGN_KEY_CHECKS=1;
    

    【讨论】:

      猜你喜欢
      • 2012-11-14
      • 2015-10-15
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 2017-03-24
      • 2018-07-06
      相关资源
      最近更新 更多