web-dev-qa-db-ja.com

HSQLDBを備えたHibernate 4.1は「データ例外:文字列データ、右打ち切り」を与える

私は非常に奇妙な問題を抱えています、som depsをプロジェクトにアップグレードしたときにそれが起こりました。

現在、次のバージョンを使用しています。

  • 春:3.1.0.RELEASE
  • 休止状態:4.1.7。最終
  • Hsqldb:2.2.8(org.hsqldb)

私は問題がファイルフィールドで何かをしなければならないと思います。 (dbfile.content)

Stacktrace:

javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not insert: [org.project.model.Cv]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.Java:1387)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.Java:1315)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.Java:1321)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.Java:843)
    at Sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
    at Java.lang.reflect.Method.invoke(Method.Java:597)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.Java:240)
    at $Proxy36.persist(Unknown Source)
    at org.project.dao.jpa.GenericDaoJpa.save(GenericDaoJpa.Java:49)
    at Sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
    at Java.lang.reflect.Method.invoke(Method.Java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.Java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.Java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.Java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:202)
    at $Proxy40.save(Unknown Source)
    at org.project.dao.CvDaoTest.updateTest(CvDaoTest.Java:77)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
    at Java.lang.reflect.Method.invoke(Method.Java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.Java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.Java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.Java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.Java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.Java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.Java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.Java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.Java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.Java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.Java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.Java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.Java:174)
    at org.Eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.Java:50)
    at org.Eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.Java:38)
    at org.Eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.Java:467)
    at org.Eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.Java:683)
    at org.Eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.Java:390)
    at org.Eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.Java:197)
Caused by: org.hibernate.exception.DataException: could not insert: [org.project.model.Cv]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.Java:102)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.Java:66)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.Java:64)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.Java:2345)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.Java:2852)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.Java:71)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.Java:273)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.Java:320)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.Java:203)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.Java:129)
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.Java:69)
    at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.Java:179)
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.Java:135)
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.Java:61)
    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.Java:808)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.Java:782)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.Java:786)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.Java:837)
    ... 45 more
Caused by: Java.sql.SQLDataException: data exception: string data, right truncation
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.Java:105)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.Java:94)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.Java:57)
    ... 60 more
Caused by: org.hsqldb.HsqlException: data exception: string data, right truncation
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.types.BinaryType.castOrConvertToType(Unknown Source)
    at org.hsqldb.types.BinaryType.convertToType(Unknown Source)
    at org.hsqldb.StatementDML.getInsertData(Unknown Source)
    at org.hsqldb.StatementInsert.getInsertValuesNavigator(Unknown Source)
    at org.hsqldb.StatementInsert.getResult(Unknown Source)
    at org.hsqldb.StatementDMQL.execute(Unknown Source)
    at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 65 more

コンソール:

INFO : org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as createClob() method threw error : Java.lang.reflect.InvocationTargetException
Hibernate: insert into Nationality (id, countryCode) values (default, ?)
Hibernate: insert into Language (id, countryCode, languageCode) values (default, ?, ?)
Hibernate: insert into Person (id, birthdate, created, email, enabled, firstName, image, lastName, lastUpdate, nationality_id, password, role, salt) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Nationality (id, countryCode) values (default, ?)
Hibernate: insert into Person (id, birthdate, created, email, enabled, firstName, image, lastName, lastUpdate, nationality_id, password, role, salt) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Company (id, name) values (default, ?)
Hibernate: insert into Language (id, countryCode, languageCode) values (default, ?, ?)
Hibernate: insert into Company (id, name) values (default, ?)
Hibernate: insert into Skill (id, company_id, created, isCategory, lastUpdate, skill_fk) values (default, ?, ?, ?, ?, ?)
Hibernate: insert into Company (id, name) values (default, ?)
Hibernate: insert into Skill (id, company_id, created, isCategory, lastUpdate, skill_fk) values (default, ?, ?, ?, ?, ?)
Hibernate: insert into Nationality (id, countryCode) values (default, ?)
Hibernate: insert into Person (id, birthdate, created, email, enabled, firstName, image, lastName, lastUpdate, nationality_id, password, role, salt) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into CourseExperience (created, lastUpdate, lastUpdatePerson_id, person_fk, endDate, startDate, id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Nationality (id, countryCode) values (default, ?)
Hibernate: insert into Person (id, birthdate, created, email, enabled, firstName, image, lastName, lastUpdate, nationality_id, password, role, salt) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into CourseExperience (created, lastUpdate, lastUpdatePerson_id, person_fk, endDate, startDate, id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into Cv (id, company, created, language, lastUpdate, lastUpdatePerson_id, name, person_fk, summary_id) values (default, ?, ?, ?, ?, ?, ?, ?, ?)
WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: -3401, SQLState: 22001
ERROR: org.hibernate.util.JDBCExceptionReporter - data exception: string data, right truncation

Cv.Java:

package org.project.model;

import Java.util.ArrayList;
import Java.util.Date;
import Java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.OrderColumn;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.project.model.interfaces.DomainObject;

@Entity
public class Cv implements DomainObject {

    private static final long serialVersionUID = -9111485038728016755L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "person_fk")
    private Person person;

    @ManyToMany
    private List<Skill> skills = new ArrayList<Skill>();

    @ManyToOne
    private Summary summary;

    @ManyToMany(targetEntity = Experience.class)
    @OrderColumn(name = "index")
    private List<Experience> experiences = new ArrayList<Experience>();

    @Temporal(TemporalType.TIMESTAMP)
    @Column(updatable = false, insertable = true)
    private Date created;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdate;

    @ManyToOne(optional = false)
    private Person lastUpdatePerson;

    @Column(nullable = false)
    private Language language;

    @Column(nullable = false)
    private Company company;

    @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL, targetEntity = DbFile.class)
    @OrderBy("created DESC")
    private List<DbFile> files = new ArrayList<DbFile>();

    @PrePersist
    @PreUpdate
    protected void updateDates() {
        Date now = new Date();
        if (this.created == null) {
            this.created = new Date(now.getTime());
        }
        this.lastUpdate = now;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public List<Skill> getSkills() {
        return skills;
    }

    public void setSkills(List<Skill> skills) {
        this.skills = skills;
    }

    public List<Experience> getExperiences() {
        return experiences;
    }

    public void setExperiences(List<Experience> experiences) {
        this.experiences = experiences;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public Person getLastUpdatePerson() {
        return lastUpdatePerson;
    }

    public void setLastUpdatePerson(Person lastUpdatePerson) {
        this.lastUpdatePerson = lastUpdatePerson;
    }

    public void addSkill(Skill skill) {
        this.skills.add(skill);
    }

    public void addExperience(Experience experience) {
        this.experiences.add(experience);
    }

    public Summary getSummary() {
        return summary;
    }

    public void setSummary(Summary summary) {
        this.summary = summary;
    }

    public List<DbFile> getFiles() {
        return files;
    }

    public void setFiles(List<DbFile> files) {
        this.files = files;
    }

    public void addFile(DbFile file) {
        this.files.add(file);
    }

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public Language getLanguage() {
        return language;
    }

    public void setLanguage(Language language) {
        this.language = language;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cv other = (Cv) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}

DbFile.Java:

package org.project.model;

import Java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.PrePersist;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Type;

import org.project.model.interfaces.DomainObject;

@Entity
public class DbFile implements DomainObject {

    private static final long serialVersionUID = 1974800702358176016L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String filename;

    @Column(nullable = false)
    @Lob
    @Type(type = "org.hibernate.type.MaterializedClobType")
    private byte[] content;

    private String contentType;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(updatable = false)
    private Date created;

    @PrePersist
    protected void updateDates() {
        if (this.created == null) {
            this.created = new Date();
        }
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Date getCreated() {
        return created;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DbFile other = (DbFile) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}

テスト:

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
...
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class CvDaoTest extends AbstractTest {

    @Autowired
    private CvDao cvDao;

    @Test
    public void updateTest() {
        Cv cv = new Cv();
        cv.setName("test");

        ...
        cv.setLastUpdatePerson(lastUpdatePerson);

        ...
        cv.setPerson(person);
        cv.setCreated(new Date());
        cv.setLastUpdate(new Date());

        cv.setCompany(getCompany());
        cv.setLanguage(getLanguage());

        ...
        cv.addSkill(skill1);
        cv.addSkill(skill2);

        ...
        cv.addExperience(experience1);
        cv.addExperience(experience2);

        cvDao.save(cv).getId();
    }
}

GenericDaoJpa.Java

public class GenericDaoJpa<T extends DomainObject> implements GenericDao<T> {

    private Class<T> type;
//  @PersistenceContext
    protected EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public GenericDaoJpa(Class<T> type) {
        super();
        this.type = type;
    }

    @Transactional(readOnly = true)
    public T get(Long id) {
        if (id == null) {
            return null;
        } else {
            return entityManager.find(type, id);
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public List<T> getAll() {
        return entityManager.createQuery("select o from " + type.getName() + " o").getResultList();
    }

    @Transactional(readOnly = false)
    public T save(T object) {
        if (object.getId() != null) {
            return entityManager.merge(object);
        } else {
            entityManager.persist(object);
        }
        entityManager.flush();
        return object;
    }

    public T delete(T object) {
        entityManager.remove(object);
        return object;
    }
}

それは失敗します: 'cvDao.save(cv).getId();'

クラス「com.mchange.v2.c3p0.ComboPooledDataSource」とドライバー「org.hsqldb.jdbcDriver」をURL「jdbc:hsqldb:mem:data」で使用するデータソース

何が悪いのでしょうか?

16
Kronis

スタックトレースが2.2.8以降に修正された問題のように見えるため、HSQLDB 2.2.9または最新のサンショットを試してください。

スナップショットとリリースの両方のMavenリポジトリは次のとおりです。

http://www.hsqldb.org/repos/org/hsqldb/hsqldb/

以下の回答もご覧ください。 「org.hibernate.type.MaterializedClobType」の使用はPostgreSQLで一般的であるようです。ただし、フィールドはbyte []であり、HSQLDBを使用したBLOBとしてより適切に表すことができます。

JDBCではなくHibernateを介してblobからイメージを取得

1
fredt

問題は、HSQLDialect実装にあり、SQL型をコンストラクターに登録します。

public HSQLDialect() {
    super();

    ...
    registerColumnType( Types.BLOB, "blob($l)" );
    registerColumnType( Types.CLOB, "clob($l)" );
    ...
}

ここで$ lcolumn length attributeから取得されます。ただし、列の長さ属性が明示的に設定されていない場合、デフォルト値は255になります。そのような場合、HSQLDialectCLOB(255)として列を作成します。

1)

1つの解決策は、列の長さを十分な値で明示的に設定することです。

例えば:

@Lob
@Column(length = 10000)
private String text;

ただし、そのような人工的な構成を避けたい場合は、方言を変更できます。

2)

2番目の解決策は、modifyHSQLDialectです。

package com.extensions.dialect;

import Java.sql.Types;
import org.hibernate.dialect.HSQLDialect;

public class MyHsqlDialect extends HSQLDialect {

    public MppHsqlDialect() {
        super();
        registerColumnType(Types.CLOB, "clob");
    }
}

休止状態の設定で新しい方言をセットアップします:

hibernate.dialect=com.extensions.dialect.MyHsqlDialect

統合テストでこのソリューションを使用しています。


いくつかの追加情報がここにあります:

https://hibernate.atlassian.net/browse/HHH-7541

26
przemek hertel

正解は次のようになります。次のように、@ Columnアノテーションに長さを追加します。

@Lob
@Column(length = 10000, name = "style")
private String style;
11
Petar Tahchiev

同様の問題がありました。エラーがたくさんありました:「データ例外:文字列データ、右打ち切り」。解決策は、大きなフィールドのサイズを指定することでした。そのフィールドがないと、デフォルトのサイズに制限されます。しかし、それだけではありません。 HSQLはデータベーススキーマを自動的に更新しません。そのため、データベースを再作成しても、変更は適用されません。

@Column(length = 5 * 1024 * 1024) // five megabytes
private byte[] bytesPreview;
5
yuliskov

リレーションシッププロパティの1つに@ManyToOneアノテーションが欠落していると、同じエラーメッセージが表示されました。 HSQLDBを2.2.9にアップグレードしても問題は解決しませんでした。

JPA 2には次の要件があります。

"関係には、@ OneToManyまたは@ManyToManyの関係アノテーションが最低限必要です。"

そのような注釈を追加せずに新しいプロパティを追加しましたか?

0
Mr Auni