14

基本的な質問: @Embedded オブジェクトが常にインスタンス化されないのはなぜですか?

興味深いことに、Ebean は @Embedded オブジェクトに基本的なデータ型 (int、boolean...) が含まれていない場合、または以前に触れられていない場合、それらのオブジェクトをインスタンス化しません。例:

@Entity
public class Embedder {
    // getNotAutoInstantiated() will return null if this field was not touched before
    @Embedded
    private NotAutoInstantiated notAutoInstantiated = new NotAutoInstantiated();
    // getAutoInstantiated() will always return an instance!
    @Embedded
    private AutoInstantiated autoInstantiated = new AutoInstantiated();
}

@Embeddable
public class AutoInstantiated {
    // theKey is why this embedded object is always instantiated
    private int theKey; 
    private String field1;      
}

@Embeddable
public class NotAutoInstantiated {
    private String field2;      
}
4

4 に答える 4

13

Hibernate については、 issue HHH-7610を確認してください。

特に、5.1 以降、この動作を変更するための実験的な機能があります。この機能には既知の問題があり、安定するまで本番環境で使用しないでください。これはorg.hibernate.cfg.AvailableSettingsの Javadoc で詳しく説明されています):

/**
 * [EXPERIMENTAL] Enable instantiation of composite/embedded objects when all of its attribute values are {@code null}.
 * The default (and historical) behavior is that a {@code null} reference will be used to represent the
 * composite when all of its attributes are {@code null}
 * <p/>
 * This is an experimental feature that has known issues. It should not be used in production
 * until it is stabilized. See Hibernate Jira issue HHH-11936 for details.
 *
 * @since 5.1
 */
String CREATE_EMPTY_COMPOSITES_ENABLED = "hibernate.create_empty_composites.enabled";

hibernate.create_empty_composites.enabledプロパティを true に設定してください。

于 2016-11-28T10:05:02.537 に答える
6

@EmbeddedJPA仕様では、オブジェクトのプロパティがすべてnullの場合に何が起こるかを明確に説明しているとは思いませんが、少なくとも一部の実装では、nullプロパティを持つオブジェクトをnullオブジェクトとして扱います。

これは合理的な実装のようです。確かに、(Hibernateを使用して)コードで@Embeddedオブジェクトをnullに設定した場合、永続化されたバージョンをロードするときにオブジェクトをnullのままにしておくと便利です。

あなたの例ではAutoInstantiated、プリミティブプロパティがnullになることはないため、クラスをnullと見なすことはtheKeyできません。

于 2012-12-22T02:34:00.367 に答える
1

オブジェクトがロードされていないときに NPE を回避し、副作用を回避するための Martin と同様のハック。

  // workaround as Embeddable objects are not loaded if all their fields are null
  public NotAutoInstantiated getNotAutoInstantiated() {
    if (notAutoInstantiated == null) {
      // WARNING! do not assign this new object to notAutoInstantiated field,
      // this would have side effects as the field is not loaded by Ebean, 
      // Ebean would try to refresh the field in some cases and another NPE would occur:
      // io.ebeaninternal.server.core.DefaultBeanLoader.refreshBeanInternal(DefaultBeanLoader.java:194)
      return new NotAutoInstantiated();
    }
    return notAutoInstantiated;
  }
于 2021-01-15T13:17:12.167 に答える