diff --git a/core/src/main/java/ai/timefold/solver/core/api/domain/autodiscover/AutoDiscoverMemberType.java b/core/src/main/java/ai/timefold/solver/core/api/domain/autodiscover/AutoDiscoverMemberType.java
deleted file mode 100644
index 77659433a0d..00000000000
--- a/core/src/main/java/ai/timefold/solver/core/api/domain/autodiscover/AutoDiscoverMemberType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package ai.timefold.solver.core.api.domain.autodiscover;
-
-import ai.timefold.solver.core.api.domain.solution.ConstraintWeightOverrides;
-import ai.timefold.solver.core.api.domain.solution.PlanningEntityCollectionProperty;
-import ai.timefold.solver.core.api.domain.solution.PlanningEntityProperty;
-import ai.timefold.solver.core.api.domain.solution.PlanningScore;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactCollectionProperty;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactProperty;
-
-/**
- * Determines if and how to automatically presume {@link ConstraintWeightOverrides},
- * {@link ProblemFactCollectionProperty}, {@link ProblemFactProperty}, {@link PlanningEntityCollectionProperty},
- * {@link PlanningEntityProperty} and {@link PlanningScore} annotations on {@link PlanningSolution} members
- * based on the member type.
- */
-public enum AutoDiscoverMemberType {
- /**
- * Do not reflect.
- */
- NONE,
- /**
- * Reflect over the fields and automatically behave as the appropriate annotation is there
- * based on the field type.
- */
- FIELD,
- /**
- * Reflect over the getter methods and automatically behave as the appropriate annotation is there
- * based on the return type.
- */
- GETTER;
-}
diff --git a/core/src/main/java/ai/timefold/solver/core/api/domain/solution/PlanningSolution.java b/core/src/main/java/ai/timefold/solver/core/api/domain/solution/PlanningSolution.java
index dedd9689bbc..560e197f4d3 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/domain/solution/PlanningSolution.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/domain/solution/PlanningSolution.java
@@ -6,12 +6,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
import ai.timefold.solver.core.api.domain.solution.cloner.SolutionCloner;
import ai.timefold.solver.core.api.score.stream.ConstraintProvider;
-import org.jspecify.annotations.NonNull;
-
/**
* Specifies that the class is a planning solution.
* A solution represents a problem and a possible solution of that problem.
@@ -42,21 +39,6 @@
@Target({ TYPE })
@Retention(RUNTIME)
public @interface PlanningSolution {
-
- /**
- * Enable reflection through the members of the class
- * to automatically assume {@link PlanningScore}, {@link PlanningEntityCollectionProperty},
- * {@link PlanningEntityProperty}, {@link ProblemFactCollectionProperty}, {@link ProblemFactProperty}
- * and {@link ConstraintWeightOverrides} annotations based on the member type.
- *
- *
- * This feature is not supported under Quarkus.
- * When using Quarkus,
- * setting this to anything other than {@link AutoDiscoverMemberType#NONE} will result in a build-time exception.
- */
- @NonNull
- AutoDiscoverMemberType autoDiscoverMemberType() default AutoDiscoverMemberType.NONE;
-
/**
* Overrides the default {@link SolutionCloner} to implement a custom {@link PlanningSolution} cloning implementation.
*
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptor.java b/core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptor.java
index 9ff642c5adf..f850e794e04 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptor.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptor.java
@@ -10,7 +10,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -34,7 +33,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
import ai.timefold.solver.core.api.domain.entity.PlanningEntity;
import ai.timefold.solver.core.api.domain.solution.ConstraintWeightOverrides;
import ai.timefold.solver.core.api.domain.solution.PlanningEntityCollectionProperty;
@@ -139,7 +137,7 @@ public static SolutionDescriptor buildSolutionDescriptor(
descriptorPolicy.setMemberAccessorFactory(solutionDescriptor.getMemberAccessorFactory());
solutionDescriptor.processUnannotatedFieldsAndMethods(descriptorPolicy);
- solutionDescriptor.processAnnotations(descriptorPolicy, entityClassList);
+ solutionDescriptor.processAnnotations(descriptorPolicy);
// Before iterating over the entity classes, we need to read the inheritance chain,
// add all parent and child classes, and sort them.
var updatedEntityClassList = new ArrayList<>(entityClassList);
@@ -259,7 +257,6 @@ private static boolean hasAnyAnnotatedMembers(Class> solutionClass) {
private final MemberAccessorFactory memberAccessorFactory;
private DomainAccessType domainAccessType;
- private AutoDiscoverMemberType autoDiscoverMemberType;
private LookUpStrategyResolver lookUpStrategyResolver;
private final Map problemFactMemberAccessorMap = new LinkedHashMap<>();
@@ -337,7 +334,7 @@ private void processConstraintWeights(DescriptorPolicy descriptorPolicy) {
}
}
- public void processAnnotations(DescriptorPolicy descriptorPolicy, List> entityClassList) {
+ public void processAnnotations(DescriptorPolicy descriptorPolicy) {
domainAccessType = descriptorPolicy.getDomainAccessType();
processSolutionAnnotations(descriptorPolicy);
var potentiallyOverwritingMethodList = new ArrayList();
@@ -356,7 +353,7 @@ public void processAnnotations(DescriptorPolicy descriptorPolicy, List>
continue;
}
processValueRangeProviderAnnotation(descriptorPolicy, member);
- processFactEntityOrScoreAnnotation(descriptorPolicy, member, entityClassList);
+ processFactEntityOrScoreAnnotation(descriptorPolicy, member);
}
potentiallyOverwritingMethodList.ensureCapacity(potentiallyOverwritingMethodList.size() + memberList.size());
memberList.stream().filter(Method.class::isInstance)
@@ -382,7 +379,6 @@ Maybe add a getScore() method with a @%s annotation."""
private void processSolutionAnnotations(DescriptorPolicy descriptorPolicy) {
var annotation = extractMostRelevantPlanningSolutionAnnotation();
- autoDiscoverMemberType = annotation.autoDiscoverMemberType();
var solutionClonerClass = annotation.solutionCloner();
if (solutionClonerClass != PlanningSolution.NullSolutionCloner.class) {
solutionCloner = ConfigUtils.newInstance(this::toString, "solutionClonerClass", solutionClonerClass);
@@ -422,9 +418,9 @@ private void processValueRangeProviderAnnotation(DescriptorPolicy descriptorPoli
}
private void processFactEntityOrScoreAnnotation(DescriptorPolicy descriptorPolicy,
- Member member, List> entityClassList) {
- var annotationClass = extractFactEntityOrScoreAnnotationClassOrAutoDiscover(
- member, entityClassList);
+ Member member) {
+ var annotationClass = extractFactEntityOrScoreAnnotationClass(
+ member);
if (annotationClass == null) {
return;
}
@@ -444,63 +440,12 @@ private void processFactEntityOrScoreAnnotation(DescriptorPolicy descriptorPolic
}
}
- private Class extends Annotation> extractFactEntityOrScoreAnnotationClassOrAutoDiscover(
- Member member, List> entityClassList) {
- var annotationClass = ConfigUtils.extractAnnotationClass(member,
+ private static Class extends Annotation> extractFactEntityOrScoreAnnotationClass(Member member) {
+ return ConfigUtils.extractAnnotationClass(member,
ProblemFactProperty.class,
ProblemFactCollectionProperty.class,
PlanningEntityProperty.class, PlanningEntityCollectionProperty.class,
PlanningScore.class);
- if (annotationClass == null) {
- Class> type;
- if (autoDiscoverMemberType == AutoDiscoverMemberType.FIELD
- && member instanceof Field field) {
- type = field.getType();
- } else if (autoDiscoverMemberType == AutoDiscoverMemberType.GETTER
- && (member instanceof Method method) && ReflectionHelper.isGetterMethod(method)) {
- type = method.getReturnType();
- } else {
- type = null;
- }
- if (type != null) {
- if (Score.class.isAssignableFrom(type)) {
- annotationClass = PlanningScore.class;
- } else if (Collection.class.isAssignableFrom(type) || type.isArray()) {
- Class> elementType;
- if (Collection.class.isAssignableFrom(type)) {
- var genericType = (member instanceof Field f) ? f.getGenericType()
- : ((Method) member).getGenericReturnType();
- var memberName = member.getName();
- if (!(genericType instanceof ParameterizedType)) {
- throw new IllegalArgumentException(
- """
- The solutionClass (%s) has a auto discovered member (%s) with a member type (%s) that returns a %s which has no generic parameters.
- Maybe the member (%s) should return a typed %s."""
- .formatted(solutionClass, memberName, type, Collection.class.getSimpleName(),
- memberName, Collection.class.getSimpleName()));
- }
- elementType = ConfigUtils.extractGenericTypeParameter("solutionClass", solutionClass, type, genericType,
- null, member.getName()).orElse(Object.class);
- } else {
- elementType = type.getComponentType();
- }
- if (entityClassList.stream().anyMatch(entityClass -> entityClass.isAssignableFrom(elementType))) {
- annotationClass = PlanningEntityCollectionProperty.class;
- } else {
- annotationClass = ProblemFactCollectionProperty.class;
- }
- } else if (Map.class.isAssignableFrom(type)) {
- throw new IllegalStateException(
- "The autoDiscoverMemberType (%s) does not yet support the member (%s) of type (%s) which is an implementation of %s."
- .formatted(autoDiscoverMemberType, member, type, Map.class.getSimpleName()));
- } else if (entityClassList.stream().anyMatch(entityClass -> entityClass.isAssignableFrom(type))) {
- annotationClass = PlanningEntityProperty.class;
- } else {
- annotationClass = ProblemFactProperty.class;
- }
- }
- }
- return annotationClass;
}
private void processProblemFactPropertyAnnotation(DescriptorPolicy descriptorPolicy, Member member,
diff --git a/core/src/test/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptorTest.java
index 01db6ec9d1a..f0c9f48f28b 100644
--- a/core/src/test/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptorTest.java
+++ b/core/src/test/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptorTest.java
@@ -1,6 +1,5 @@
package ai.timefold.solver.core.impl.domain.solution.descriptor;
-import static ai.timefold.solver.core.testutil.PlannerAssert.assertAllCodesOfCollection;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -10,19 +9,15 @@
import java.util.Arrays;
import java.util.List;
-import ai.timefold.solver.core.api.score.SimpleScore;
import ai.timefold.solver.core.impl.domain.entity.descriptor.EntityDescriptor;
import ai.timefold.solver.core.impl.domain.valuerange.descriptor.AbstractValueRangeDescriptor;
import ai.timefold.solver.core.impl.domain.variable.descriptor.BasicVariableDescriptor;
-import ai.timefold.solver.core.impl.score.definition.SimpleScoreDefinition;
import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
import ai.timefold.solver.core.testdomain.TestdataValue;
import ai.timefold.solver.core.testdomain.collection.TestdataArrayBasedSolution;
import ai.timefold.solver.core.testdomain.collection.TestdataSetBasedSolution;
import ai.timefold.solver.core.testdomain.immutable.enumeration.TestdataEnumSolution;
import ai.timefold.solver.core.testdomain.immutable.record.TestdataRecordSolution;
-import ai.timefold.solver.core.testdomain.inheritance.solution.baseannotated.childnot.TestdataOnlyBaseAnnotatedChildEntity;
import ai.timefold.solver.core.testdomain.inheritance.solution.baseannotated.childtoo.TestdataBothAnnotatedExtendedSolution;
import ai.timefold.solver.core.testdomain.invalid.badfactcollection.TestdataBadFactCollectionSolution;
import ai.timefold.solver.core.testdomain.invalid.constraintweightoverrides.TestdataInvalidConstraintWeightOverridesSolution;
@@ -38,21 +33,13 @@
import ai.timefold.solver.core.testdomain.solutionproperties.TestdataProblemFactPropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.TestdataReadMethodProblemFactCollectionPropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.TestdataWildcardSolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataAutoDiscoverFieldOverrideSolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataAutoDiscoverFieldSolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataAutoDiscoverGetterOverrideSolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataAutoDiscoverGetterSolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataAutoDiscoverUnannotatedEntitySolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.autodiscover.TestdataExtendedAutoDiscoverGetterSolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataDuplicatePlanningEntityCollectionPropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataDuplicatePlanningScorePropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataDuplicateProblemFactCollectionPropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataMissingScorePropertySolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataProblemFactCollectionPropertyWithArgumentSolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataProblemFactIsPlanningEntityCollectionPropertySolution;
-import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataUnknownFactTypeSolution;
import ai.timefold.solver.core.testdomain.solutionproperties.invalid.TestdataUnsupportedWildcardSolution;
-import ai.timefold.solver.core.testutil.CodeAssertableArrayList;
import ai.timefold.solver.core.testutil.PlannerTestUtils;
import org.junit.jupiter.api.Test;
@@ -203,137 +190,6 @@ void generic() {
.containsOnlyKeys("value", "subTypeValue", "complexGenericValue");
}
- // ************************************************************************
- // Autodiscovery
- // ************************************************************************
-
- @Test
- void autoDiscoverProblemFactCollectionPropertyElementTypeUnknown() {
- assertThatIllegalArgumentException().isThrownBy(TestdataUnknownFactTypeSolution::buildSolutionDescriptor);
- }
-
- @Test
- void autoDiscoverFields() {
- var solutionDescriptor = TestdataAutoDiscoverFieldSolution.buildSolutionDescriptor();
- assertThat(solutionDescriptor.getScoreDefinition()).isInstanceOf(SimpleScoreDefinition.class);
- assertThat(solutionDescriptor.getScoreDefinition().getScoreClass()).isEqualTo(SimpleScore.class);
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).containsOnlyKeys("problemFactList");
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var valueList = Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2"));
- var entityList = Arrays.asList(new TestdataEntity("e1"), new TestdataEntity("e2"));
- var otherEntity = new TestdataEntity("otherE1");
- var solution = new TestdataAutoDiscoverFieldSolution("s1", singleProblemFact, valueList, entityList, otherEntity);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution), "otherE1", "p1", "e1", "e2",
- "v1", "v2");
- }
-
- @Test
- void autoDiscoverGetters() {
- var solutionDescriptor = TestdataAutoDiscoverGetterSolution.buildSolutionDescriptor();
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).containsOnlyKeys("problemFactList");
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var valueList = Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2"));
- var entityList = Arrays.asList(new TestdataEntity("e1"), new TestdataEntity("e2"));
- var otherEntity = new TestdataEntity("otherE1");
- var solution = new TestdataAutoDiscoverGetterSolution("s1", singleProblemFact, valueList, entityList, otherEntity);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution), "otherE1", "p1", "e1", "e2",
- "v1", "v2");
- }
-
- @Test
- void autoDiscoverFieldsFactCollectionOverriddenToSingleProperty() {
- var solutionDescriptor = TestdataAutoDiscoverFieldOverrideSolution.buildSolutionDescriptor();
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact",
- "listProblemFact");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).containsOnlyKeys("problemFactList");
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var valueList = Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2"));
- var entityList = Arrays.asList(new TestdataEntity("e1"), new TestdataEntity("e2"));
- var otherEntity = new TestdataEntity("otherE1");
- var listFact = new CodeAssertableArrayList<>("list1", Arrays.asList("x", "y"));
- var solution = new TestdataAutoDiscoverFieldOverrideSolution("s1", singleProblemFact, valueList, entityList,
- otherEntity, listFact);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution),
- "otherE1", "list1", "p1", "e1", "e2", "v1", "v2");
- }
-
- @Test
- void autoDiscoverGettersFactCollectionOverriddenToSingleProperty() {
- var solutionDescriptor = TestdataAutoDiscoverGetterOverrideSolution.buildSolutionDescriptor();
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact",
- "listProblemFact");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).containsOnlyKeys("problemFactList");
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var valueList = Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2"));
- var entityList = Arrays.asList(new TestdataEntity("e1"), new TestdataEntity("e2"));
- var otherEntity = new TestdataEntity("otherE1");
- var listFact = new CodeAssertableArrayList<>("list1", Arrays.asList("x", "y"));
- var solution = new TestdataAutoDiscoverGetterOverrideSolution("s1", singleProblemFact, valueList, entityList,
- otherEntity, listFact);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution),
- "otherE1", "list1", "p1", "e1", "e2", "v1", "v2");
- }
-
- @Test
- void autoDiscoverUnannotatedEntitySubclass() {
- var solutionDescriptor = TestdataAutoDiscoverUnannotatedEntitySolution.buildSolutionDescriptor();
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).containsOnlyKeys("problemFactList");
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var valueList = Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2"));
- var entityList = Arrays.asList(
- new TestdataOnlyBaseAnnotatedChildEntity("u1"),
- new TestdataOnlyBaseAnnotatedChildEntity("u2"));
- var otherEntity = new TestdataOnlyBaseAnnotatedChildEntity("otherU1");
- var solution =
- new TestdataAutoDiscoverUnannotatedEntitySolution("s1", singleProblemFact, valueList, entityList, otherEntity);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution), "otherU1", "p1", "u1", "u2",
- "v1", "v2");
- }
-
- @Test
- void autoDiscoverGettersOverriddenInSubclass() {
- var solutionDescriptor = TestdataExtendedAutoDiscoverGetterSolution.buildSubclassSolutionDescriptor();
- assertThat(solutionDescriptor.getProblemFactMemberAccessorMap()).containsOnlyKeys("singleProblemFact",
- "problemFactList");
- assertThat(solutionDescriptor.getProblemFactCollectionMemberAccessorMap()).isEmpty();
- assertThat(solutionDescriptor.getEntityMemberAccessorMap()).containsOnlyKeys("otherEntity");
- assertThat(solutionDescriptor.getEntityCollectionMemberAccessorMap()).containsOnlyKeys("entityList");
-
- var singleProblemFact = new TestdataObject("p1");
- var listAsSingleProblemFact =
- new CodeAssertableArrayList<>("f1", Arrays.asList(new TestdataValue("v1"), new TestdataValue("v2")));
- var entityList = Arrays.asList(new TestdataEntity("e1"), new TestdataEntity("e2"));
- var otherEntity = new TestdataEntity("otherE1");
- var solution = new TestdataExtendedAutoDiscoverGetterSolution("s1", singleProblemFact, listAsSingleProblemFact,
- entityList, otherEntity);
-
- assertAllCodesOfCollection(solutionDescriptor.getAllEntitiesAndProblemFacts(solution), "otherE1", "f1", "p1", "e1",
- "e2");
- }
-
@Test
void testImmutableClass() {
assertThatCode(TestdataRecordSolution::buildSolutionDescriptor)
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldOverrideSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldOverrideSolution.java
deleted file mode 100644
index 232e2cbddf6..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldOverrideSolution.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactProperty;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)
-public class TestdataAutoDiscoverFieldOverrideSolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(TestdataAutoDiscoverFieldOverrideSolution.class,
- TestdataEntity.class);
- }
-
- private TestdataObject singleProblemFact;
- @ValueRangeProvider(id = "valueRange")
- private List problemFactList;
- @ProblemFactProperty // would have been autodiscovered as @ProblemFactCollectionProperty
- private List listProblemFact;
-
- private List entityList;
- private TestdataEntity otherEntity;
-
- private SimpleScore score;
-
- public TestdataAutoDiscoverFieldOverrideSolution() {
- }
-
- public TestdataAutoDiscoverFieldOverrideSolution(String code) {
- super(code);
- }
-
- public TestdataAutoDiscoverFieldOverrideSolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataEntity otherEntity, List listFact) {
- super(code);
- this.singleProblemFact = singleProblemFact;
- this.problemFactList = problemFactList;
- this.entityList = entityList;
- this.otherEntity = otherEntity;
- this.listProblemFact = listFact;
- }
-
- public SimpleScore getScore() {
- return score;
- }
-
- public void setScore(SimpleScore score) {
- this.score = score;
- }
-
- public TestdataObject getSingleProblemFact() {
- return singleProblemFact;
- }
-
- public void setSingleProblemFact(TestdataObject singleProblemFact) {
- this.singleProblemFact = singleProblemFact;
- }
-
- public List getProblemFactList() {
- return problemFactList;
- }
-
- public void setProblemFactList(List problemFactList) {
- this.problemFactList = problemFactList;
- }
-
- public List getListProblemFact() {
- return listProblemFact;
- }
-
- public void setListProblemFact(List listProblemFact) {
- this.listProblemFact = listProblemFact;
- }
-
- public List getEntityList() {
- return entityList;
- }
-
- public void setEntityList(List entityList) {
- this.entityList = entityList;
- }
-
- public TestdataEntity getOtherEntity() {
- return otherEntity;
- }
-
- public void setOtherEntity(TestdataEntity otherEntity) {
- this.otherEntity = otherEntity;
- }
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldSolution.java
deleted file mode 100644
index 18ed54fb70b..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverFieldSolution.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)
-public class TestdataAutoDiscoverFieldSolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(TestdataAutoDiscoverFieldSolution.class, TestdataEntity.class);
- }
-
- private TestdataObject singleProblemFact;
- @ValueRangeProvider(id = "valueRange")
- private List problemFactList;
-
- private List entityList;
- private TestdataEntity otherEntity;
-
- private SimpleScore score;
-
- public TestdataAutoDiscoverFieldSolution() {
- }
-
- public TestdataAutoDiscoverFieldSolution(String code) {
- super(code);
- }
-
- public TestdataAutoDiscoverFieldSolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataEntity otherEntity) {
- super(code);
- this.singleProblemFact = singleProblemFact;
- this.problemFactList = problemFactList;
- this.entityList = entityList;
- this.otherEntity = otherEntity;
- }
-
- public SimpleScore getScore() {
- return score;
- }
-
- public void setScore(SimpleScore score) {
- this.score = score;
- }
-
- public TestdataObject getSingleProblemFact() {
- return singleProblemFact;
- }
-
- public void setSingleProblemFact(TestdataObject singleProblemFact) {
- this.singleProblemFact = singleProblemFact;
- }
-
- public List getProblemFactList() {
- return problemFactList;
- }
-
- public void setProblemFactList(List problemFactList) {
- this.problemFactList = problemFactList;
- }
-
- public List getEntityList() {
- return entityList;
- }
-
- public void setEntityList(List entityList) {
- this.entityList = entityList;
- }
-
- public TestdataEntity getOtherEntity() {
- return otherEntity;
- }
-
- public void setOtherEntity(TestdataEntity otherEntity) {
- this.otherEntity = otherEntity;
- }
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterOverrideSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterOverrideSolution.java
deleted file mode 100644
index 24ae215d156..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterOverrideSolution.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactProperty;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.GETTER)
-public class TestdataAutoDiscoverGetterOverrideSolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(
- TestdataAutoDiscoverGetterOverrideSolution.class, TestdataEntity.class);
- }
-
- private TestdataObject singleProblemFactField;
- private List problemFactListField;
- private List listProblemFactField;
-
- private List entityListField;
- private TestdataEntity otherEntityField;
-
- private SimpleScore score;
-
- public TestdataAutoDiscoverGetterOverrideSolution() {
- }
-
- public TestdataAutoDiscoverGetterOverrideSolution(String code) {
- super(code);
- }
-
- public TestdataAutoDiscoverGetterOverrideSolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataEntity otherEntity, List listFact) {
- super(code);
- this.singleProblemFactField = singleProblemFact;
- this.problemFactListField = problemFactList;
- this.entityListField = entityList;
- this.otherEntityField = otherEntity;
- this.listProblemFactField = listFact;
- }
-
- public TestdataObject getSingleProblemFact() {
- return singleProblemFactField;
- }
-
- @ValueRangeProvider(id = "valueRange")
- public List getProblemFactList() {
- return problemFactListField;
- }
-
- @ProblemFactProperty // would have been autodiscovered as @ProblemFactCollectionProperty
- public List getListProblemFact() {
- return listProblemFactField;
- }
-
- public List getEntityList() {
- return entityListField;
- }
-
- public TestdataEntity getOtherEntity() {
- return otherEntityField;
- }
-
- public SimpleScore getScore() {
- return score;
- }
-
- public void setScore(SimpleScore score) {
- this.score = score;
- }
-
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterSolution.java
deleted file mode 100644
index 89c9123da6f..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverGetterSolution.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.GETTER)
-public class TestdataAutoDiscoverGetterSolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(TestdataAutoDiscoverGetterSolution.class, TestdataEntity.class);
- }
-
- private TestdataObject singleProblemFactField;
- private List problemFactListField;
-
- private List entityListField;
- private TestdataEntity otherEntityField;
-
- private SimpleScore score;
-
- public TestdataAutoDiscoverGetterSolution() {
- }
-
- public TestdataAutoDiscoverGetterSolution(String code) {
- super(code);
- }
-
- public TestdataAutoDiscoverGetterSolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataEntity otherEntity) {
- super(code);
- this.singleProblemFactField = singleProblemFact;
- this.problemFactListField = problemFactList;
- this.entityListField = entityList;
- this.otherEntityField = otherEntity;
- }
-
- public TestdataObject getSingleProblemFact() {
- return singleProblemFactField;
- }
-
- @ValueRangeProvider(id = "valueRange")
- public List getProblemFactList() {
- return problemFactListField;
- }
-
- public List getEntityList() {
- return entityListField;
- }
-
- public TestdataEntity getOtherEntity() {
- return otherEntityField;
- }
-
- public SimpleScore getScore() {
- return score;
- }
-
- public void setScore(SimpleScore score) {
- this.score = score;
- }
-
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverUnannotatedEntitySolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverUnannotatedEntitySolution.java
deleted file mode 100644
index 8e7429a3870..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataAutoDiscoverUnannotatedEntitySolution.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-import ai.timefold.solver.core.testdomain.inheritance.solution.baseannotated.childnot.TestdataOnlyBaseAnnotatedChildEntity;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.GETTER)
-public class TestdataAutoDiscoverUnannotatedEntitySolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(
- TestdataAutoDiscoverUnannotatedEntitySolution.class, TestdataOnlyBaseAnnotatedChildEntity.class);
- }
-
- private TestdataObject singleProblemFactField;
- private List problemFactListField;
-
- private List entityListField;
- private TestdataOnlyBaseAnnotatedChildEntity otherEntityField;
-
- private SimpleScore score;
-
- public TestdataAutoDiscoverUnannotatedEntitySolution() {
- }
-
- public TestdataAutoDiscoverUnannotatedEntitySolution(String code) {
- super(code);
- }
-
- public TestdataAutoDiscoverUnannotatedEntitySolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataOnlyBaseAnnotatedChildEntity otherEntity) {
- super(code);
- this.singleProblemFactField = singleProblemFact;
- this.problemFactListField = problemFactList;
- this.entityListField = entityList;
- this.otherEntityField = otherEntity;
- }
-
- public TestdataObject getSingleProblemFact() {
- return singleProblemFactField;
- }
-
- @ValueRangeProvider(id = "valueRange")
- public List getProblemFactList() {
- return problemFactListField;
- }
-
- // should be auto discovered as an entity collection
- public List getEntityList() {
- return entityListField;
- }
-
- // should be auto discovered as a single entity property
- public TestdataOnlyBaseAnnotatedChildEntity getOtherEntity() {
- return otherEntityField;
- }
-
- public SimpleScore getScore() {
- return score;
- }
-
- public void setScore(SimpleScore score) {
- this.score = score;
- }
-
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataExtendedAutoDiscoverGetterSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataExtendedAutoDiscoverGetterSolution.java
deleted file mode 100644
index b755b250b64..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/autodiscover/TestdataExtendedAutoDiscoverGetterSolution.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.autodiscover;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactProperty;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.GETTER)
-public class TestdataExtendedAutoDiscoverGetterSolution extends TestdataAutoDiscoverGetterSolution {
-
- public static SolutionDescriptor buildSubclassSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(TestdataExtendedAutoDiscoverGetterSolution.class,
- TestdataEntity.class);
- }
-
- private TestdataObject singleProblemFactFieldOverride;
- private List problemFactListFieldOverride;
-
- private List entityListFieldOverride;
- private TestdataEntity otherEntityFieldOverride;
-
- public TestdataExtendedAutoDiscoverGetterSolution() {
- }
-
- public TestdataExtendedAutoDiscoverGetterSolution(String code) {
- super(code);
- }
-
- public TestdataExtendedAutoDiscoverGetterSolution(String code, TestdataObject singleProblemFact,
- List problemFactList, List entityList,
- TestdataEntity otherEntity) {
- super(code);
- this.singleProblemFactFieldOverride = singleProblemFact;
- this.problemFactListFieldOverride = problemFactList;
- this.entityListFieldOverride = entityList;
- this.otherEntityFieldOverride = otherEntity;
- }
-
- @Override
- public TestdataObject getSingleProblemFact() {
- return singleProblemFactFieldOverride;
- }
-
- @ProblemFactProperty // Override from a fact collection to a single fact
- @ValueRangeProvider(id = "valueRange")
- @Override
- public List getProblemFactList() {
- return problemFactListFieldOverride;
- }
-
- @Override
- public List getEntityList() {
- return entityListFieldOverride;
- }
-
- @Override
- public TestdataEntity getOtherEntity() {
- return otherEntityFieldOverride;
- }
-
-}
diff --git a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/invalid/TestdataUnknownFactTypeSolution.java b/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/invalid/TestdataUnknownFactTypeSolution.java
deleted file mode 100644
index 7c6fc9e1db0..00000000000
--- a/core/src/test/java/ai/timefold/solver/core/testdomain/solutionproperties/invalid/TestdataUnknownFactTypeSolution.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package ai.timefold.solver.core.testdomain.solutionproperties.invalid;
-
-import java.util.Collection;
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.valuerange.ValueRangeProvider;
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
-import ai.timefold.solver.core.testdomain.TestdataEntity;
-import ai.timefold.solver.core.testdomain.TestdataObject;
-import ai.timefold.solver.core.testdomain.TestdataValue;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)
-public class TestdataUnknownFactTypeSolution extends TestdataObject {
-
- public static SolutionDescriptor buildSolutionDescriptor() {
- return SolutionDescriptor.buildSolutionDescriptor(TestdataUnknownFactTypeSolution.class,
- TestdataEntity.class);
- }
-
- private List valueList;
- private List entityList;
- private SimpleScore score;
- // this can't work with autodiscovery because it's difficult/impossible to resolve the type of collection elements
- private MyStringCollection facts;
-
- public TestdataUnknownFactTypeSolution() {
- }
-
- public TestdataUnknownFactTypeSolution(String code) {
- super(code);
- }
-
- @ValueRangeProvider(id = "valueRange")
- public List getValueList() {
- return valueList;
- }
-
- public MyStringCollection getFacts() {
- return facts;
- }
-
- public static interface MyStringCollection extends Collection {
-
- }
-}
diff --git a/docs/TODO.md b/docs/TODO.md
index df692a1d046..e020ae1ccaf 100644
--- a/docs/TODO.md
+++ b/docs/TODO.md
@@ -31,5 +31,6 @@
- [ ] domain.lookup package is gone, so is lookup from PlanningSolution.
- [ ] lookups no longer accept null values.
- [ ] `DomainAccessType` is gone, code uses GIZMO when possible
+- [ ] `AutoDiscoverMemberType` is gone
Remove this file when done.
\ No newline at end of file
diff --git a/docs/src/modules/ROOT/pages/using-timefold-solver/modeling-planning-problems.adoc b/docs/src/modules/ROOT/pages/using-timefold-solver/modeling-planning-problems.adoc
index f59888b241b..15213918e1f 100644
--- a/docs/src/modules/ROOT/pages/using-timefold-solver/modeling-planning-problems.adoc
+++ b/docs/src/modules/ROOT/pages/using-timefold-solver/modeling-planning-problems.adoc
@@ -2426,7 +2426,6 @@ In rare cases, a planning entity might be a singleton: use `@PlanningEntityPrope
Both annotations need to be on a member in a class with a `@PlanningSolution` annotation,
and are ignored on parent classes or subclasses without that annotation.
-They can also be <> if enabled.
IMPORTANT: A planning solution must not contain duplicate entities,
as defined by the `equals()` method of the entity class.
@@ -2474,8 +2473,6 @@ public class Timetable {
Some use cases use xref:constraints-and-score/overview.adoc#scoreType[other score types].
-This annotation can also be <> if enabled.
-
[#problemFacts]
=== Problem facts of a solution (`@ProblemFactCollectionProperty`)
@@ -2531,8 +2528,6 @@ It is ignored on parent classes or subclasses without that annotation.
In rare cases, a problem fact might be a singleton: use `@ProblemFactProperty` on its method (or field) instead.
-Both annotations can also be <> if enabled.
-
[#cachedProblemFact]
==== Cached problem fact
@@ -2580,41 +2575,6 @@ Where a score constraint needs to check that no two exams with a topic that shar
the `TopicConflict` instance can be used as a problem fact, rather than having to combine every two `Student` instances.
-[#autoDiscoverSolutionProperties]
-=== Auto discover solution properties
-
-Instead of configuring each property (or field) annotation explicitly,
-some can also be deduced automatically by Timefold Solver:
-
-[source,java,options="nowrap"]
-----
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)
-public class VehicleRoutePlan {
-
- ...
-
-}
-----
-
-The `AutoDiscoverMemberType` can be:
-
-* `NONE`: No auto discovery.
-* `FIELD`: Auto discover all fields on the `@PlanningSolution` class
-* `GETTER`: Auto discover all getters on the `@PlanningSolution` class
-
-The automatic annotation is based on the field type (or getter return type):
-
-* `@ProblemFactProperty`: when it isn't a `Collection`, an array, a `@PlanningEntity` class or a `Score`
-* `@ProblemFactCollectionProperty`: when it's a `Collection` (or array) of a type that isn't a `@PlanningEntity` class
-* `@PlanningEntityProperty`: when it is a configured `@PlanningEntity` class or subclass
-* `@PlanningEntityCollectionProperty`: when it's a `Collection` (or array) of a type that is a configured `@PlanningEntity` class or subclass
-* `@PlanningScore`: when it is a `Score` or subclass
-
-These automatic annotations can still be overwritten per field (or getter).
-Specifically, a xref:constraints-and-score/overview.adoc#bendableScore[BendableScore] always needs to override
-with an explicit `@PlanningScore` annotation to define the number of hard and soft levels.
-
-
[#cloningASolution]
=== Cloning a solution
diff --git a/quarkus-integration/quarkus/deployment/src/main/java/ai/timefold/solver/quarkus/deployment/TimefoldProcessor.java b/quarkus-integration/quarkus/deployment/src/main/java/ai/timefold/solver/quarkus/deployment/TimefoldProcessor.java
index 400cbb72284..4827bf74250 100644
--- a/quarkus-integration/quarkus/deployment/src/main/java/ai/timefold/solver/quarkus/deployment/TimefoldProcessor.java
+++ b/quarkus-integration/quarkus/deployment/src/main/java/ai/timefold/solver/quarkus/deployment/TimefoldProcessor.java
@@ -24,12 +24,8 @@
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Singleton;
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
import ai.timefold.solver.core.api.domain.entity.PlanningEntity;
-import ai.timefold.solver.core.api.domain.solution.PlanningEntityCollectionProperty;
-import ai.timefold.solver.core.api.domain.solution.PlanningScore;
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.domain.solution.ProblemFactCollectionProperty;
import ai.timefold.solver.core.api.domain.variable.ShadowSources;
import ai.timefold.solver.core.api.domain.variable.ShadowVariable;
import ai.timefold.solver.core.api.score.calculator.EasyScoreCalculator;
@@ -65,7 +61,6 @@
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
-import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
@@ -1001,28 +996,6 @@ private GeneratedGizmoClasses generateDomainAccessors(Map
PlanningSolution.class.getSimpleName()));
}
- planningSolutionAnnotationInstanceCollection.forEach(planningSolutionAnnotationInstance -> {
- var autoDiscoverMemberType = planningSolutionAnnotationInstance.values().stream()
- .filter(v -> v.name().equals("autoDiscoverMemberType"))
- .findFirst()
- .map(AnnotationValue::asEnum)
- .map(AutoDiscoverMemberType::valueOf)
- .orElse(AutoDiscoverMemberType.NONE);
-
- if (autoDiscoverMemberType != AutoDiscoverMemberType.NONE) {
- throw new UnsupportedOperationException("""
- Auto-discovery of members using %s is not supported under Quarkus.
- Remove the autoDiscoverMemberType property from the @%s annotation
- and explicitly annotate the fields or getters with annotations such as @%s, @%s or @%s."""
- .strip()
- .formatted(
- AutoDiscoverMemberType.class.getSimpleName(),
- PlanningSolution.class.getSimpleName(),
- PlanningScore.class.getSimpleName(),
- PlanningEntityCollectionProperty.class.getSimpleName(),
- ProblemFactCollectionProperty.class.getSimpleName()));
- }
- });
var solutionClassInstance = planningSolutionAnnotationInstanceCollection.iterator().next();
var solutionClassInfo = solutionClassInstance.target().asClass();
var visited = new HashSet();
diff --git a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverFieldTest.java b/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverFieldTest.java
deleted file mode 100644
index cb9d134afe6..00000000000
--- a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverFieldTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package ai.timefold.solver.quarkus;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.fail;
-
-import ai.timefold.solver.quarkus.testdomain.gizmo.DummyConstraintProvider;
-import ai.timefold.solver.quarkus.testdomain.gizmo.TestDataKitchenSinkAutoDiscoverFieldSolution;
-import ai.timefold.solver.quarkus.testdomain.gizmo.TestDataKitchenSinkEntity;
-
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.spec.JavaArchive;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import io.quarkus.test.QuarkusUnitTest;
-
-class TimefoldProcessorGizmoKitchenSinkAutoDiscoverFieldTest {
-
- @RegisterExtension
- static final QuarkusUnitTest config = new QuarkusUnitTest()
- .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
- .addClasses(TestDataKitchenSinkAutoDiscoverFieldSolution.class,
- TestDataKitchenSinkEntity.class,
- DummyConstraintProvider.class))
- .assertException(t -> assertThat(t)
- .isInstanceOf(UnsupportedOperationException.class)
- .hasMessageContaining("autoDiscoverMemberType"));
-
- @Test
- void solve() {
- fail("The build should fail");
- }
-
-}
diff --git a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverMethodTest.java b/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverMethodTest.java
deleted file mode 100644
index cfa7791d7e9..00000000000
--- a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorGizmoKitchenSinkAutoDiscoverMethodTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package ai.timefold.solver.quarkus;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertSame;
-
-import jakarta.inject.Inject;
-
-import ai.timefold.solver.core.api.score.SimpleScore;
-import ai.timefold.solver.core.api.solver.SolutionManager;
-import ai.timefold.solver.core.api.solver.SolverFactory;
-import ai.timefold.solver.core.api.solver.SolverManager;
-import ai.timefold.solver.core.impl.solver.DefaultSolutionManager;
-import ai.timefold.solver.core.impl.solver.DefaultSolverFactory;
-import ai.timefold.solver.core.impl.solver.DefaultSolverManager;
-import ai.timefold.solver.quarkus.testdomain.gizmo.DummyConstraintProvider;
-import ai.timefold.solver.quarkus.testdomain.gizmo.TestDataKitchenSinkAutoDiscoverMethodSolution;
-import ai.timefold.solver.quarkus.testdomain.gizmo.TestDataKitchenSinkEntity;
-
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.spec.JavaArchive;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-import io.quarkus.test.QuarkusUnitTest;
-
-class TimefoldProcessorGizmoKitchenSinkAutoDiscoverMethodTest {
-
- @RegisterExtension
- static final QuarkusUnitTest config = new QuarkusUnitTest()
- .overrideConfigKey("quarkus.timefold.solver.termination.best-score-limit", "0hard/0soft")
- .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
- .addClasses(TestDataKitchenSinkAutoDiscoverMethodSolution.class,
- TestDataKitchenSinkEntity.class,
- DummyConstraintProvider.class))
- .assertException(t -> assertThat(t)
- .isInstanceOf(UnsupportedOperationException.class)
- .hasMessageContaining("autoDiscoverMemberType"));
-
- @Inject
- SolverFactory solverFactory;
- @Inject
- SolverManager solverManager;
- @Inject
- SolutionManager solutionManager;
-
- @Test
- void singletonSolverFactory() {
- assertNotNull(solverFactory);
- // There is only one ScoreDirectorFactory instance
- assertSame(((DefaultSolverFactory>) solverFactory).getScoreDirectorFactory(),
- ((DefaultSolutionManager, ?>) solutionManager).getScoreDirectorFactory());
- assertNotNull(solverManager);
- // There is only one SolverFactory instance
- assertSame(solverFactory,
- ((DefaultSolverManager) solverManager).getSolverFactory());
- }
-
- @Test
- void solve() { // The method exists only so that the class is considered a test.
- throw new IllegalStateException("The test is expected to fail before it even gets here.");
- }
-
-}
diff --git a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverFieldSolution.java b/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverFieldSolution.java
deleted file mode 100644
index bc783031c6a..00000000000
--- a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverFieldSolution.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package ai.timefold.solver.quarkus.testdomain.gizmo;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.score.HardSoftScore;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)
-public class TestDataKitchenSinkAutoDiscoverFieldSolution {
-
- private TestDataKitchenSinkEntity planningEntityProperty;
- private List planningEntityListProperty;
- private String problemFactProperty;
- private List problemFactListProperty;
- private HardSoftScore score;
-
- public TestDataKitchenSinkAutoDiscoverFieldSolution() {
-
- }
-
- public TestDataKitchenSinkAutoDiscoverFieldSolution(TestDataKitchenSinkEntity planningEntityProperty,
- List planningEntityListProperty, String problemFactProperty,
- List problemFactListProperty, HardSoftScore score) {
- this.planningEntityProperty = planningEntityProperty;
- this.planningEntityListProperty = planningEntityListProperty;
- this.problemFactProperty = problemFactProperty;
- this.problemFactListProperty = problemFactListProperty;
- this.score = score;
- }
-
- public TestDataKitchenSinkEntity getPlanningEntityProperty() {
- return planningEntityProperty;
- }
-
- public HardSoftScore getScore() {
- return score;
- }
-}
diff --git a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverMethodSolution.java b/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverMethodSolution.java
deleted file mode 100644
index aeb1d4f6deb..00000000000
--- a/quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/gizmo/TestDataKitchenSinkAutoDiscoverMethodSolution.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package ai.timefold.solver.quarkus.testdomain.gizmo;
-
-import java.util.List;
-
-import ai.timefold.solver.core.api.domain.autodiscover.AutoDiscoverMemberType;
-import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
-import ai.timefold.solver.core.api.score.HardSoftScore;
-
-@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.GETTER)
-public class TestDataKitchenSinkAutoDiscoverMethodSolution {
-
- private TestDataKitchenSinkEntity planningEntityProperty;
- private List planningEntityListProperty;
- private String problemFactProperty;
- private List problemFactListProperty;
- private HardSoftScore score;
-
- public TestDataKitchenSinkAutoDiscoverMethodSolution() {
-
- }
-
- public TestDataKitchenSinkAutoDiscoverMethodSolution(TestDataKitchenSinkEntity planningEntityProperty,
- List planningEntityListProperty, String problemFactProperty,
- List problemFactListProperty, HardSoftScore score) {
- this.planningEntityProperty = planningEntityProperty;
- this.planningEntityListProperty = planningEntityListProperty;
- this.problemFactProperty = problemFactProperty;
- this.problemFactListProperty = problemFactListProperty;
- this.score = score;
- }
-
- public TestDataKitchenSinkEntity getPlanningEntityProperty() {
- return planningEntityProperty;
- }
-
- public void setPlanningEntityProperty(TestDataKitchenSinkEntity planningEntityProperty) {
- this.planningEntityProperty = planningEntityProperty;
- }
-
- public List getPlanningEntityListProperty() {
- return planningEntityListProperty;
- }
-
- public void setPlanningEntityListProperty(List planningEntityListProperty) {
- this.planningEntityListProperty = planningEntityListProperty;
- }
-
- public String getProblemFactProperty() {
- return problemFactProperty;
- }
-
- public void setProblemFactProperty(String problemFactProperty) {
- this.problemFactProperty = problemFactProperty;
- }
-
- public List getProblemFactListProperty() {
- return problemFactListProperty;
- }
-
- public void setProblemFactListProperty(List problemFactListProperty) {
- this.problemFactListProperty = problemFactListProperty;
- }
-
- public HardSoftScore getScore() {
- return score;
- }
-
- public void setScore(HardSoftScore score) {
- this.score = score;
- }
-}