決定的なHibernateの本「Java persistence with Hibernate」は、 hibernate.hbm2ddl.autoの更新値についてこれに言及しています(太字は私のものです)
この構成プロパティの追加オプションである update は、開発中に役立ちます。組み込みの SchemaUpdate ツールが有効になり、スキーマの進化が容易になります。有効にすると、Hibernate は起動時に JDBC データベースのメタデータを読み取り、古いスキーマを現在のマッピング メタデータと比較して新しいテーブルと制約を作成します。この機能は、JDBC ドライバーによって提供されるメタデータの品質に依存することに注意してください。これは、多くのドライバーが不足している領域です。したがって、実際には、この機能は思ったほど刺激的でも有用でもありません。
また、Hibernateのドキュメントはここで同じことを示唆しています
SchemaUpdate ツールは、既存のスキーマを「増分」変更で更新します。SchemaUpdate は JDBC メタデータ API に依存しているため、すべての JDBC ドライバーで機能するとは限りません。
私はあなたのユースケースを再現しようとしましたが、私もこの問題を抱えていたことに驚きました.
このようなユーザーエンティティがあります
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Table( name = "usr" )
public class User {
@Id
@GeneratedValue
private Long id;
@Column( length = 40, unique = true )
private String name;
@Lob
@Column( length = 100000 )
private String text;
public long getId() {
return id;
}
public void setName( String name ) {
this.name = name;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
public void setText( String text ) {
this.text = text;
}
}
私の永続性xmlはこのようなものです
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="jpatest" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpadatabase"/>
<property name="hibernate.show-sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
hibernate.hbm2ddl.auto の値を変更してエンティティのテキスト プロパティを作成し、これに変更すると、
.....
@Column( length = 255 )
private String text;
......
スキーマ ジェネレーターは、起動時に次の sql を生成します。
DEBUG SchemaExport:415 - drop table if exists usr
DEBUG SchemaExport:415 - create table usr (id bigint not null auto_increment, name varchar(40) unique, text varchar(255), primary key (id)) ENGINE=InnoDB
INFO SchemaExport:281 - schema export complete
エンティティのプロパティを再度変更する
.....
@Lob
@Column( length = 100000 )
private String text;
.......
次の正しいSQLが生成されるようになりました
DEBUG SchemaExport:415 - drop table if exists usr
DEBUG SchemaExport:415 - create table usr (id bigint not null auto_increment, name varchar(40) unique, text longtext, primary key (id)) ENGINE=InnoDB
INFO SchemaExport:281 - schema export complete
ここまでは順調ですね。
値 hibernate.hbm2ddl.auto を更新して同じ順序でエンティティの上記の変更を繰り返すと、テキスト列を varchar(255) から LONGTEXT に更新したにもかかわらず、更新列 sql は生成されません。
INFO TableMetadata:65 - table found: jpadatabase.usr
INFO TableMetadata:66 - columns: [id, text, name]
INFO TableMetadata:68 - foreign keys: []
INFO TableMetadata:69 - indexes: [name, primary]
DEBUG DefaultIdentifierGeneratorFactory:90 - Setting dialect [org.hibernate.dialect.MySQL5InnoDBDialect]
INFO SchemaUpdate:217 - schema update complete
ただし、更新を使用していて、プロパティを変更する代わりに、別のプロパティの場所を追加すると、正しい SQL が再度生成されます。
DEBUG SchemaUpdate:203 - alter table usr add column location varchar(255)
INFO SchemaUpdate:217 - schema update complete
したがって、本質的に、作成 (最初にテーブルを削除してから再作成する) は正しく機能しますが、プロパティ メタデータに変更がある場合、更新は機能しません。
私には、インクリメンタル アップデートのドライバー サポートの問題がここで発生しているように見えます。これも直感的に考えると、列のデータ型の更新をサポートしても意味がありません。変更された列のデータ型が以前のデータ型の縮小バージョンである場合、既存のデータはどうなりますか。