public final class CustomerEditModel extends SwingEntityEditModel {

  public CustomerEditModel(EntityConnectionProvider connectionProvider) {
    super(Customer.TYPE, connectionProvider);
    editor().comboBoxModels().initialize(Customer.SUPPORTREP_FK);
    // Set a detail editor, in order to edit customer preferences alongside the customer
    SwingEntityEditor preferences = new SwingEntityEditor(Preferences.TYPE, connectionProvider);
    preferences.value(Preferences.PREFERRED_GENRE_FK).persist().set(false);
    preferences.comboBoxModels().initialize(Preferences.PREFERRED_GENRE_FK);
    editor().detail().add(EditorLink.builder()
            .editor(preferences)
            .foreignKey(Preferences.CUSTOMER_FK)
            .present(new PreferencesPresent())
            .build());
  }

  private static final class PreferencesPresent implements Predicate<Entity> {

    @Override
    public boolean test(Entity preferences) {
      // Preferences without both preferred genre and newsletter are deleted
      return !preferences.isNull(Preferences.PREFERRED_GENRE_FK) ||
              !preferences.isNull(Preferences.NEWSLETTER);
    }
  }
}
public final class ArtistEditModel extends SwingEntityEditModel {

  public static final int TAG_SLOTS = 6;
  public static final String TAG_PREFIX = "tag";

  public ArtistEditModel(EntityConnectionProvider connectionProvider) {
    super(Artist.TYPE, connectionProvider);
    TagPresent present = new TagPresent();
    for (int i = 0; i < TAG_SLOTS; i++) {
      editor().detail().add(EditorLink.builder()
              .editor(new SwingEntityEditor(ArtistTag.TYPE, connectionProvider))
              .foreignKey(ArtistTag.ARTIST_FK)
              .entity(new TagEntity(i))
              .present(present)
              .name(TAG_PREFIX + i)
              .caption("(" + (i + 1) + ")")
              .build());
    }
  }

  private static final class TagEntity implements DetailEntity {

    private final int index;

    private TagEntity(int index) {
      this.index = index;
    }

    @Override
    public @Nullable Entity detail(Entity artist, EntityConnection connection) {
      List<Entity> tags = connection.select(where(ArtistTag.ARTIST_FK.equalTo(artist))
              .orderBy(ascending(ArtistTag.TAG))
              .referenceDepth(0)
              .offset(index)
              .limit(1));

      return tags.isEmpty() ? null : tags.get(0);
    }
  }

  private static final class TagPresent implements Predicate<Entity> {

    @Override
    public boolean test(Entity tag) {
      return !tag.isNull(ArtistTag.TAG);
    }
  }
}