Hello

Firstly, let me comment on the @Named behavior - for standard beans, CDI picks a default name if you don't specify it within the annotation's value.
See also https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0#default_name
Although I am not quite sure what would/should happen if you did just that on a synthetic bean...

As for BeanConfigurator#name() - this sets the EL name of the bean so that the bean is resolvable with just its name instead of type/qualifiers.
It however side steps the need to add @Named qualifier so it then cannot be used as a qualifier during typesafe resolution which is why you saw the failure.

Lastly, the @Named qualifier should not be used as a plain differentiator between various implementations - it has a special role for EL naming and more importantly special qualifier treatment!
The specification states that @Named at injection points is not recommended (https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0#named_at_injection_point) and the reason for that is that, unlike any other custom qualifier, presence of @Named does *not* prevent the bean from automatically getting the built-in @Default qualifier (as stated in https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0#builtin_qualifiers).
This means that beans @Named("a") Foo and @Named("b") Foo are both valid candidates for the an injection point that requires just the type (@Inject Foo fooField).

For instance SR created a dedicated annotation (@Identifier) to avoid this behavior - https://github.com/smallrye/smallrye-common/blob/main/annotation/src/main/java/io/smallrye/common/annotation/Identifier.java#L13-L18

Regards
Matej

On Wed, Aug 6, 2025 at 11:48 PM Scott Marlow via weld-dev <weld-dev@lists.jboss.org> wrote:


On Wed, Aug 6, 2025 at 5:20 PM Scott Marlow <smarlow@redhat.com> wrote:
I'm running the following code in WildFly to create an EntityManagerFactory CDI bean for application deployments to use but I don't seem to be able to use the passed bean name ("pu1") in a test that has:
"
@Inject
@Named("pu1")
EntityManagerFactory entityManagerFactoryByPuName;
"
I expect that the following container code is naming the created bean but I thought the passed name would work with @Named but it doesn't seem to.  The following EE container code (AfterBeanDiscovery callback) is doing the following which includes a call to "beanConfigurator.name(persistenceUnitMetadata.getPersistenceUnitName()):".  Should setting the bean name this way allow @Named references to the passed name ("pu1" in this case) lookup the created bean as I am showing above?
"
private void
entityManagerFactory(
AfterBeanDiscovery afterBeanDiscovery,
PersistenceUnitMetadata persistenceUnitMetadata,
List<String> qualifiers,
IntegrationWithCDIBag integrationWithCDIBag) throws InstantiationException, IllegalAccessException {

String scope = applicationScoped;

// EntityManagerFactory setup
BeanConfigurator<EntityManagerFactory> beanConfigurator = afterBeanDiscovery.addBean();
beanConfigurator.addTransitiveTypeClosure(EntityManagerFactory.class);

try {
if (!persistenceUnitMetadata.isDuplicate()) {
beanConfigurator.name(persistenceUnitMetadata.getPersistenceUnitName());
I added a call to "beanConfigurator.addQualifier(NamedLiteral.of(persistenceUnitMetadata.getPersistenceUnitName()))" and that seemed to help my unit test to be able to lookup the created CDI bean via "@Inject @Named("pu1") EntityManagerFactory entityManagerFactoryByPuName;"
Still, I'm curious as to what the call to BeanConfigurator.name(String) accomplishes?  
Does that make it possible to do the bean injection a different way?
Thanks,
Scott
        }
Class<? extends Annotation> scopeAnnotation = persistenceUnitMetadata.getClassLoader().loadClass(scope).asSubclass(Annotation.class);
beanConfigurator.scope(scopeAnnotation);

for (String qualifier : qualifiers) {
final Class<? extends Annotation> qualifierType = persistenceUnitMetadata.getClassLoader()
.loadClass(qualifier)
.asSubclass(Annotation.class);
beanConfigurator.addQualifier(ScopeProxy.createProxy(qualifierType));
}
Class<?> entityManagerFactoryClass = EntityManagerFactory.class;
beanConfigurator.beanClass(entityManagerFactoryClass);
beanConfigurator.produceWith(c -> {
return integrationWithCDIBag.getEntityManagerFactory();
}
);
} catch (ClassNotFoundException e) {
throw JpaLogger.ROOT_LOGGER.classNotFound(e, persistenceUnitMetadata.getScopedPersistenceUnitName());
}
}
"

Thanks,
Scott
_______________________________________________
weld-dev mailing list -- weld-dev@lists.jboss.org
To unsubscribe send an email to weld-dev-leave@lists.jboss.org
Privacy Statement: https://www.redhat.com/en/about/privacy-policy
List Archives: https://lists.jboss.org/archives/list/weld-dev@lists.jboss.org/message/QVDOWJLJIUDCIR6AIHMBMZQQ6HWR4MEA/