4

親愛なるプログラマーの皆さん、私は次のことを支援するためにあなたのところに来ました:

アプリケーションの ORM として EclipseLink を使用しており、エンティティ (記事) の 1 つにソフト削除を実装し、OneToMany 関係を持つカテゴリが削除されたときにこれらの記事をカスケード削除しようとしています。

記事を削除するとすべてが期待どおりに機能しますが、記事が n 個あるカテゴリを削除すると例外が発生します。DescriptorCustomizer を使用してソフト削除を実行しています。

次の実装を持つDescriptorCustomizer ( org.eclipse.persistence.config.DescriptorCustomizerを参照):

public class ArticleCustomizer implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor classDescriptor) throws Exception {
       classDescriptor.getQueryManager().setDeleteSQLString("UPDATE article SET ACTIVE = '0' WHERE id = #id");
    }
}

保存しようとしているエンティティ:

AbstractItem

@Entity
@Table(name = "item")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractItem extends BaseEntity {
    @ManyToOne
protected Category category;
}

論文

@Entity
@DiscriminatorValue("article")
@Customizer(value=ArticleCustomizer.class)
public class Article extends AbstractItem {

}

カテゴリー

@Entity
@Customizer(value=CategoryCustomizer.class)
public class Category extends BaseEntity {

    @OneToMany(cascade = CascadeType.REMOVE)
    @JoinTable(name = "category_items", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
    protected List<AbstractItem> items = new ArrayList<AbstractItem>();

    @OneToMany(cascade = CascadeType.REMOVE)
    @JoinTable(name = "category_subcategories", joinColumns = @JoinColumn(name = "category_id"), inverseJoinColumns = @JoinColumn(name = "parent_category_id"))
    protected List<Category> categories = new ArrayList<Category>();
}

n 個の記事を持つカテゴリをカスケード削除しようとすると、次のエラーが表示されます。

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'ACTIVE' in 'field list'
Error Code: 1054
Call: UPDATE article SET ACTIVE = '0' WHERE id = ?
bind => [null]

ID が null にバインドされていることがわかりますが、その理由はわかりません。誰かが私を正しい方向に導いてくれますか?

  1. Eclipselink バージョン: 2.4.0
  2. 春: 3.1.2RELEASE

ありがとうございました!

4

2 に答える 2

4

お時間を頂戴してしまい申し訳ございません。解決策は私の目の前にありました:

classDescriptor.getQueryManager().setDeleteSQLString("UPDATE item SET ACTIVE = '0' WHERE id = #ID");

カスタマイザの正しいテーブルは、ARTICLEではなくITEMである必要があります。奇妙なことに、単一の記事の削除では機能し、カスケードでは機能しませんでした。

2番目の問題は次のとおりです。

#id instead of #ID

大文字と小文字が区別されます。

私を助けてくれてありがとう!

于 2012-10-23T19:34:59.037 に答える
0

クラスが実装するときはいつでも、DescriptorCustomizerそのコーディングを次のようにラップすることをお勧めします。

public static class MyCustomizer implements DescriptorCustomizer {
    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        try {
           ...
           ... your functionality 
           ...
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
}

その理由は、ログ設定が(非常に詳細な)DescriptorCustomizerよりも低い場合に、サイレント エラーが発生するためです。FINERその場合、例外は「外部」に伝播されず、それらの通知を受け取ることも、失敗の理由を見つけることもできません。

または、EMF プロパティPersistenceUnitProperties.LOGGING_LEVELのレベルを に設定することもできますSessionLog.FINER_LABEL

于 2015-10-18T15:36:22.423 に答える