001package io.ebean.annotation;
002
003import java.lang.annotation.ElementType;
004import java.lang.annotation.Retention;
005import java.lang.annotation.RetentionPolicy;
006import java.lang.annotation.Target;
007
008/**
009 * Used to control which ToMany relationships are preferred as 'joins' rather than
010 * as 'secondary joins' (query fetches).
011 * <p>
012 * Ebean automatically limits the number of SQL joins to ToMany relationships to avoid
013 * SQL cartesian product and to honor SQL first row / max rows limits. It does this by
014 * allowing the first ToMany relationship/path that has been defined on a query to be
015 * included in the main query as a join and then converting any remaining ToMany
016 * relationship/path to "query joins".
017 * </p>
018 * <p>
019 * Without explicit use of <code>@FetchPreference</code> the first path that contains a
020 * ToMany is included in the main query as a join.
021 * </p>
022 *
023 * <p>
024 * Indicate to Ebean the preferred relationships to join to.
025 * </p>
026 * <h2>Example</h2>
027 * <p>
028 * Prefer joins to 'participants' over 'messages'
029 * </p>
030 * <pre>{@code
031 *
032 *     @FetchPreference(1)
033 *     @OneToMany(mappedBy = "conversation")
034 *     List<Participation> participants;
035 *
036 *     @FetchPreference(2)
037 *     @OneToMany(mappedBy = "conversation")
038 *     List<Message> messages;
039 *
040 * }</pre>
041 *
042 * <h2>Example query that is impacted</h2>
043 * <pre>{@code
044 *
045 *  // Without @FetchPreference the first ToMany which
046 *  // is "messages" is joined and "participants" is
047 *  // query joined (executed as a secondary query)
048 *
049 *  Ebean.find(Conversation.class)
050 *      .fetch("messages")         // <- first ToMany path Ebean sees
051 *      .fetch("participants")     // <- second ToMany path Ebean sees
052 *      .findList();
053 *
054 * }</pre>
055 *
056 */
057@Retention(RetentionPolicy.RUNTIME)
058@Target({ElementType.FIELD})
059public @interface FetchPreference {
060
061        /**
062         * The fetch preference used - low value means higher preference.
063         */
064        int value();
065}