Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3455 - Improve query beans such that filterMany() expressions are only on ToMany relationships #3473

Merged
merged 2 commits into from
Sep 17, 2024

Conversation

rbygrave
Copy link
Member

@rbygrave rbygrave commented Sep 9, 2024

Changes the query bean code generation for "Associated beans" to have separate AssocOne and AssocMany for *ToOne and *ToMany relationships.

Moves the filterMany() expressions such that they are only available on the *ToMany relationships.

…ly on ToMany relationships

Changes the query bean code generation for "Associated beans" to have separate AssocOne and AssocMany for *ToOne and *ToMany relationships.

Moves the filterMany() expressions such that they are only available on the *ToMany relationships.
@rbygrave rbygrave self-assigned this Sep 9, 2024
…ly on ToMany relationships

Use protected helper methods on TQAssocBean for the filterMany() methods generated onto AssocMany beans.
@rbygrave
Copy link
Member Author

rbygrave commented Sep 9, 2024

Example generated query bean with AssocOne and AssocMany:

package org.example.domain.query;

import io.ebean.typequery.PBoolean;
import io.ebean.typequery.PByteArray;
import io.ebean.typequery.PEnum;
import io.ebean.typequery.PInet;
import io.ebean.typequery.PLong;
import io.ebean.typequery.PScalar;
import io.ebean.typequery.PScalarComparable;
import io.ebean.typequery.PString;
import io.ebean.typequery.PTimestamp;
import io.ebean.typequery.PUtilDate;
import org.example.domain.Customer.Status;
import org.example.domain.otherpackage.PhoneNumber;
import org.example.domain.otherpackage.ValidEmail;
import org.example.domain.query.QAddress;
import org.example.domain.query.QContact;

/**
 * Query bean for Customer.
 * <p>
 * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.
 */
@SuppressWarnings("unused")
@io.ebean.typequery.Generated("io.ebean.querybean.generator")
@io.ebean.typequery.TypeQueryBean("v1")
public final class QCustomer extends io.ebean.typequery.QueryBean<org.example.domain.Customer,QCustomer> {

  private static final QCustomer _alias = new QCustomer(true);

  /**
   * Return the shared 'Alias' instance used to provide properties to 
   * <code>select()</code> and <code>fetch()</code> 
   */
  public static QCustomer alias() {
    return _alias;
  }

  public PLong<QCustomer> id;
  public PLong<QCustomer> version;
  public PTimestamp<QCustomer> whenCreated;
  public PTimestamp<QCustomer> whenUpdated;
  public PEnum<QCustomer,Status> status;
  public PBoolean<QCustomer> inactive;
  public PScalar<QCustomer, PhoneNumber> phoneNumber;
  public PScalarComparable<QCustomer, ValidEmail> email;
  public PString<QCustomer> name;
  public PUtilDate<QCustomer> registered;
  public PInet<QCustomer> currentInet;
  public PString<QCustomer> comments;
  public QAddress.AssocOne<QCustomer> billingAddress;
  public QAddress.AssocOne<QCustomer> shippingAddress;
  public QContact.AssocMany<QCustomer> contacts;
  public PByteArray<QCustomer> photo;


  /**
   * Return a query bean used to build a FetchGroup.
   * <p>
   * FetchGroups are immutable and threadsafe and can be used by many
   * concurrent queries. We typically stored FetchGroup as a static final field.
   * <p>
   * Example creating and using a FetchGroup.
   * <pre>{@code
   * 
   * static final FetchGroup<Customer> fetchGroup = 
   *   QCustomer.forFetchGroup()
   *     .shippingAddress.fetch()
   *     .contacts.fetch()
   *     .buildFetchGroup();
   * 
   * List<Customer> customers = new QCustomer()
   *   .select(fetchGroup)
   *   .findList();
   * 
   * }</pre>
   */
  public static QCustomer forFetchGroup() {
    return new QCustomer(io.ebean.FetchGroup.queryFor(org.example.domain.Customer.class));
  }

  /** Construct using the default Database */
  public QCustomer() {
    super(org.example.domain.Customer.class);
  }

  /** @deprecated migrate to query.usingTransaction() */
  @Deprecated(forRemoval = true)
  public QCustomer(io.ebean.Transaction transaction) {
    super(org.example.domain.Customer.class, transaction);
  }

  /** Construct with a given Database */
  public QCustomer(io.ebean.Database database) {
    super(org.example.domain.Customer.class, database);
  }


  /** Private constructor for Alias */
  private QCustomer(boolean dummy) {
    super(dummy);
  }

  /** Private constructor for FetchGroup building */
  private QCustomer(io.ebean.Query<org.example.domain.Customer> fetchGroupQuery) {
    super(fetchGroupQuery);
  }

  /** Private constructor for filterMany */
  private QCustomer(io.ebean.ExpressionList<org.example.domain.Customer> filter) {
    super(filter);
  }

  /** Return a copy of the query bean. */
  @Override
  public QCustomer copy() {
    return new QCustomer(query().copy());
  }

  /**
   * Provides static properties to use in <em> select() and fetch() </em>
   * clauses of a query. Typically referenced via static imports. 
   */
  @io.ebean.typequery.Generated("io.ebean.querybean.generator")
  public static final class Alias {
    public static PLong<QCustomer> id = _alias.id;
    public static PLong<QCustomer> version = _alias.version;
    public static PTimestamp<QCustomer> whenCreated = _alias.whenCreated;
    public static PTimestamp<QCustomer> whenUpdated = _alias.whenUpdated;
    public static PEnum<QCustomer,Status> status = _alias.status;
    public static PBoolean<QCustomer> inactive = _alias.inactive;
    public static PScalar<QCustomer, PhoneNumber> phoneNumber = _alias.phoneNumber;
    public static PScalarComparable<QCustomer, ValidEmail> email = _alias.email;
    public static PString<QCustomer> name = _alias.name;
    public static PUtilDate<QCustomer> registered = _alias.registered;
    public static PInet<QCustomer> currentInet = _alias.currentInet;
    public static PString<QCustomer> comments = _alias.comments;
    public static QAddress.AssocOne<QCustomer> billingAddress = _alias.billingAddress;
    public static QAddress.AssocOne<QCustomer> shippingAddress = _alias.shippingAddress;
    public static QContact.AssocMany<QCustomer> contacts = _alias.contacts;
    public static PByteArray<QCustomer> photo = _alias.photo;
  }

  /** Association query bean */
  @io.ebean.typequery.Generated("io.ebean.querybean.generator")
  @io.ebean.typequery.TypeQueryBean("v1")
  public static abstract class Assoc<R> extends io.ebean.typequery.TQAssocBean<org.example.domain.Customer,R,QCustomer> {

    public PLong<R> id;
    public PLong<R> version;
    public PTimestamp<R> whenCreated;
    public PTimestamp<R> whenUpdated;
    public PEnum<R,Status> status;
    public PBoolean<R> inactive;
    public PScalar<R, PhoneNumber> phoneNumber;
    public PScalarComparable<R, ValidEmail> email;
    public PString<R> name;
    public PUtilDate<R> registered;
    public PInet<R> currentInet;
    public PString<R> comments;
    public QAddress.AssocOne<R> billingAddress;
    public QAddress.AssocOne<R> shippingAddress;
    public QContact.AssocMany<R> contacts;
    public PByteArray<R> photo;

    protected Assoc(String name, R root) { super(name, root); }
    protected Assoc(String name, R root, String prefix) { super(name, root, prefix); }
  }

  /** Associated ToOne query bean */
  @io.ebean.typequery.Generated("io.ebean.querybean.generator")
  @io.ebean.typequery.TypeQueryBean("v1")
  public static final class AssocOne<R> extends Assoc<R> {
    public AssocOne(String name, R root) { super(name, root); }
    public AssocOne(String name, R root, String prefix) { super(name, root, prefix); }
  }

  /** Associated ToMany query bean */
  @io.ebean.typequery.Generated("io.ebean.querybean.generator")
  @io.ebean.typequery.TypeQueryBean("v1")
  public static final class AssocMany<R> extends Assoc<R> implements io.ebean.typequery.TQAssocMany<org.example.domain.Customer, R, QCustomer>{
    public AssocMany(String name, R root) { super(name, root); }
    public AssocMany(String name, R root, String prefix) { super(name, root, prefix); }

    @Override
    public R filterMany(java.util.function.Consumer<QCustomer> apply) {
      final io.ebean.ExpressionList<org.example.domain.Customer> list = _newExpressionList();
      apply.accept(new QCustomer(list));
      return _filterMany(list);
    }

    @Override
    public R filterMany(io.ebean.ExpressionList<org.example.domain.Customer> filter) { return _filterMany(filter); }

    @Override
    public R filterManyRaw(String rawExpressions, Object... params) { return _filterManyRaw(rawExpressions, params); }

    @Override
    @Deprecated(forRemoval = true)
    public R filterMany(String expressions, Object... params) { return _filterMany(expressions, params); }

    @Override
    public R isEmpty() { return _isEmpty(); }

    @Override
    public R isNotEmpty() { return _isNotEmpty(); }
  }
}

@rbygrave rbygrave linked an issue Sep 9, 2024 that may be closed by this pull request
@rbygrave rbygrave added this to the 15.6.0 milestone Sep 16, 2024
@rbygrave rbygrave merged commit 5095583 into master Sep 17, 2024
1 check passed
@rbygrave rbygrave deleted the feature/3455-query-beans-improvement branch September 17, 2024 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

filterMany has no effect on OneToOne
1 participant