Skip to content

[2.7] Close #1806 - Have to the ability to dynamically set the Validation Group during a transaction #2010

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

Open
wants to merge 3 commits into
base: 2.7
Choose a base branch
from

Conversation

exabrial
Copy link

@exabrial exabrial commented Nov 28, 2023

Hello, this PR Close #1806 for the 2.7 branch. The goal here is to allow a user to specify a validation group that should be executed when persisting. I'm hoping to sort of model this how the schema-per-tenant properties work (Which is very handy btw).

I have a signed ECA, but this is my first PR for EclipseLink so I could use some feedback. If this gets merged, then I'll port the changes to the other branches seeing active development.

Thank you!

@exabrial exabrial changed the title Close #1806 - Have to the ability to dynamically set the Validation Group during a transaction [2.7] Close #1806 - Have to the ability to dynamically set the Validation Group during a transaction Nov 30, 2023
@exabrial
Copy link
Author

Hello Eclipselink team, hoping for comment and suggested improvements. Thank you

Copy link
Contributor

@rfelcman rfelcman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. For functional changes like this we expect some test (in this case integration test). Please check and maybe extend jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/beanvalidation/BeanValidationJunitTest.java
  2. Please ensure, that copyright year in the modified files is updated.

@exabrial
Copy link
Author

Thank you for the direction! I really appreciate it. We'll get to work on these things.

@exabrial
Copy link
Author

This pul isn't abandoned, just still figuring out how to write tests :)

@exabrial exabrial marked this pull request as draft August 12, 2024 16:10
@exabrial exabrial force-pushed the issues/1806_dynamic-validation-groups-on-entitymanager branch from 2f39761 to ce8a62e Compare August 12, 2024 18:44
@exabrial
Copy link
Author

still haven't abandoned this, I'll get to it.

@exabrial exabrial force-pushed the issues/1806_dynamic-validation-groups-on-entitymanager branch from fea8c89 to ce8a62e Compare May 19, 2025 16:11
@rfelcman
Copy link
Contributor

Please check and sign eclipsefdn/eca

@exabrial exabrial requested a review from rfelcman May 19, 2025 16:49
@exabrial exabrial force-pushed the issues/1806_dynamic-validation-groups-on-entitymanager branch 2 times, most recently from e53295c to 37d396f Compare May 19, 2025 16:56
@exabrial exabrial marked this pull request as ready for review May 19, 2025 16:57
@exabrial exabrial force-pushed the issues/1806_dynamic-validation-groups-on-entitymanager branch from 37d396f to e50fd9a Compare May 19, 2025 17:13
…t the Validation Group during a transaction. Add tests, update copyright headers.
@exabrial exabrial force-pushed the issues/1806_dynamic-validation-groups-on-entitymanager branch from dfffbd6 to 115e40b Compare May 19, 2025 17:38
@exabrial
Copy link
Author

Please check and sign eclipsefdn/eca

It's all good now! there was an errant signature

// This might be corrected in next iteration of spec
validateOnCallbackEvent(event, "prePersist", groupPrePersit);
Object overrideGroups = event.getSession().getParent().getProperties().get(EntityManagerProperties.VALIDATION_GROUP_PRE_PERSIST);
Copy link
Contributor

Copy link
Author

@exabrial exabrial May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I don't think I understand what you're saying.

Perhaps this is the confusion: my patch is designed to allow the user to override these settings during execution. Otherwise the validation groups are fixed in stone and cannot be modified.

Sorry I'm missing something obvious I feel like

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, that locations which are mentioned in the links are correct where new EntityManager properties should be evaluated like other properties. Not there. This is not consistent with other EntityManager properties or PersistenceUnit bean validation properties.

Copy link
Author

@exabrial exabrial May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you again for working with me. I read all three of your examples. I'm not trying to say my code is perfect (totally aware of my absolute average skills) however, I don't think I can do use them for this purpose.

Perhaps a use case would be beneficial? Here is the scenario. We have a form where the user provides 'tidbits' of information as they progress through the form. We want to save those off to db as we go. However, eventually all of the fields need to be required. Why is this a problem currently? Well JPA only allows validation groups to be defined for an EntityManger at the time of creation. When your container is injecting these persistence contexts for you, you can override them. Thats what this patch does. Take a look here:

import javax.enterprise.context.ApplicationScoped;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;

import org.eclipse.persistence.config.EntityManagerProperties;

import lombok.Data;

@ApplicationScoped
@Transactional(TxType.MANDATORY)
public class YeeHahDatabaseService {
	@PersistenceContext(unitName = "superbiz-model")
	private EntityManager em;

	public void addContact(final String contactName) {
		final SuperBizContact contact = new SuperBizContact();
		contact.setName(contactName);
		em.persist(contact); // Would throw an error because phone is marked notNull! But I don't have phone yet!
	}

	public void addContactWithPhone(final String contactName, final String phone) {
		final SuperBizContact contact = new SuperBizContact();
		contact.setName(contactName);
		contact.setPhone(phone);
		em.persist(contact); // All good here, both fields set
	}

	public void addContatc2(final String contactName) {
		final SuperBizContact contact = new SuperBizContact();
		contact.setName(contactName);
		em.setProperty(EntityManagerProperties.VALIDATION_GROUP_PRE_PERSIST, NameOnly.class);
		em.persist(contact); // This time the persist works!
	}

	@Data
	@Entity
	public class SuperBizContact {
		@Column
		@NotNull(groups = { Default.class, NameOnly.class })
		private String name;
		@Column
		@NotNull
		private String phone;
	}

	public @interface NameOnly {
	}
}

Example 1/2: EntityManagerSetupImpl.java as far as I can tell, this code has already fired by the time the dev sees the injection.

Example 3: BeanValidationInitializationHelper same here. This code has fired already when the dev see the injection.

The purpose of this property is to allow the dev to set the EntityManager for the current @PersistenceContext rather than reading it from an unmodifiable configuration XML (which is actually already supported).

if(!unitOfWork.isObjectDeleted(source)) {
validateOnCallbackEvent(event, "preUpdate", groupPreUpdate);
if (!unitOfWork.isObjectDeleted(source)) {
Object overrideGroups = event.getSession().getParent().getProperties().get(EntityManagerProperties.VALIDATION_GROUP_PRE_UPDATE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

if(groupPreRemove != null) { //No validation performed on preRemove if user has not explicitly specified a validation group
validateOnCallbackEvent(event, "preRemove", groupPreRemove);
}
Object overrideGroups = event.getSession().getParent().getProperties().get(EntityManagerProperties.VALIDATION_GROUP_PRE_REMOVE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@exabrial
Copy link
Author

@rfelcman If I could have a bit of feedback, I added several tests, but I'm not convinced they're actually running, because I never see them in the junit test report html. Whats the ant command to run an individual test class? I've tried several things:

  • ~/opensource/eclipselink$ ant -f antbuild.xml test-jpa test-core
  • ~/opensource/eclipselink$ ant -f antbuild.xml test-jpa -Dtestcase=BeanValidationJunitTest

Any help appreciated!

@rfelcman
Copy link
Contributor

@rfelcman If I could have a bit of feedback, I added several tests, but I'm not convinced they're actually running, because I never see them in the junit test report html. Whats the ant command to run an individual test class? I've tried several things:

* `~/opensource/eclipselink$ ant -f antbuild.xml test-jpa test-core`

* `~/opensource/eclipselink$ ant -f antbuild.xml test-jpa -Dtestcase=BeanValidationJunitTest`

Any help appreciated!

ant -f antbuild.xml test-jpa22 is better

Individual test class in 2.7 (Ant build) is complicated. It's easier start with other higher branches (3.0 and above) which are based on Maven and make backport.

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.

2 participants