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

Introduce 'merge' attribute for util namespace collection elements [SPR-6523] #11189

Closed
spring-projects-issues opened this issue Dec 4, 2009 · 11 comments
Assignees
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Dec 4, 2009

Sam Brannen opened SPR-6523 and commented

Section C.2.2.4 util:list/ of the reference manual states:

Finally, you can also control the merging behavior using the 'merge' attribute of the util:list/ element; collection merging is described in more detail in the section called "Collection merging".

This is, however, not true. In contrast to the standard support for collections (i.e., array, list, set, map) in the beans namespace, the util namespace does not support the merge attribute for collections.

Is this an oversight in the documentation or missing functionality in the util namespace support?

On a related note (perhaps worthy of its own JIRA issue), given the following application context configuration and JUnit test class...

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

  <bean id="listHolderParent" class="com.example.MergedListTests$ListHolder"
    abstract="true">
    <property name="list">
      <list>
        <value>red</value>
        <value>green</value>
        <value>blue</value>
      </list>
    </property>
  </bean>

  <bean id="listHolder" parent="listHolderParent">
    <property name="list">
      <list merge="true">
        <value>cyan</value>
        <value>magenta</value>
        <value>yellow</value>
        <value>black</value>
      </list>
    </property>
  </bean>

</beans>
package com.example;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MergedListTests {

  @Test
  public void mergedList() {
    ApplicationContext appCtx = new ClassPathXmlApplicationContext(
      "/com/example/MergedListTests-context.xml");
    ListHolder listHolder = appCtx.getBean("listHolder", ListHolder.class);
    assertNotNull(listHolder);
    assertEquals(7, listHolder.getList().size());
  }

  public static class ListHolder {

    private List<String> list;

    public List<String> getList() {
      return this.list;
    }

    public void setList(List<String> list) {
      this.list = list;
    }
  }
}

... changing the definition in listHolderParent to util:list results in the following exception:

java.lang.IllegalArgumentException: Cannot merge with object of type [class org.springframework.beans.factory.config.BeanDefinitionHolder]
at org.springframework.beans.factory.support.ManagedList.merge(ManagedList.java:98)
at org.springframework.beans.factory.support.ManagedList.merge(ManagedList.java:1)
at org.springframework.beans.MutablePropertyValues.mergeIfRequired(MutablePropertyValues.java:221)
at org.springframework.beans.MutablePropertyValues.addPropertyValue(MutablePropertyValues.java:169)
at org.springframework.beans.MutablePropertyValues.addPropertyValues(MutablePropertyValues.java:138)
at org.springframework.beans.factory.support.AbstractBeanDefinition.overrideFrom(AbstractBeanDefinition.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1114)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1054)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1040)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:294)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:578)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:398)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.example.MergedListTests.mergedList(MergedListTests.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...


Issue Links:

Referenced from: commits a827ab8

16 votes, 18 watchers

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 7, 2009

Juergen Hoeller commented

This is basically a limitation in the util namespace: There simply is no merge support there yet, and in particular no interaction with plain <list> merging. We'll revisit this during the 3.0.x phase.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 25, 2010

Chris Pimlott commented

At least the documentation should be updated, since it explicitly says merge is supported in each of the util schema collection types.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 27, 2010

Sam Brannen commented

FYI: I've commented out all paragraphs (i.e., for list, map, and set) in the reference manual related to collection merging with the util namespace until this issue has been addressed.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jun 30, 2010

Ian Brandt commented

Duplicate of #9872?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jul 1, 2010

Sam Brannen commented

Perhaps in fact a duplicate

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 5, 2011

Stevo Slavić commented

Maybe something similar to properties-ref of context:property-placeholder can be supported for collections and properties in util namespace.

With this, one could define:

<util:properties id="someProperties" properties-ref="someOtherProperties">
  ...
</util:properties>
<util:list id="someList" collection-ref="someOtherList">
  ...
</util:list>

<util:list id="someOtherList" collection-ref="someSet">
  ...
</util:list>

<util:set id="someSet" collection-ref="someOtherSet" ignore-colissions="false">
  ...
</util:set>

<util:set id="someOtherSet" collection-ref="yetAnotherList" ignore-colissions="true">
  ...
</util:set>

<util:list id="yetAnotherList">
  ...
</util:list>
<util:map id="someMap" map-ref="someOtherMap" ignore-colissions="false">
  ...
</util:map>

<util:map id="someOtherMap">
  ...
</util:map>

ignore-colissions can default to false with a meaning that merge should fail if destination already contains elements/entries from source. If set to true spring should ignore/skip this check, or optionally log a info/warning when colission occurs.

For properties it's a bit tricky, since it already supports additional properties to be provided via location attribute, it would be good if both location and properties-ref can be used.

I prefer -ref over merge convention requested in #9872 as I find it confusing to have different beans with same id in same context, and id would have to become not unique. Behavior somewhat equivavalent to merge can be achieved with profiles support already added in spring 3.1 M1 with -ref attribute support - one could define a single common base bean which is always active, and for different profiles/environments activate a different bean, with same id, like in following example:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/util
		http://www.springframework.org/schema/util/spring-util-3.1.xsd">

  <util:properties id="quartzCommonProperties"
        location="classpath:foo/bar/cfg/quartz-common.properties" />

  <bean id="clusteredQuartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
      p:quartzProperties-ref="quartzProperties" />

  <beans profile="production">
      <util:properties id="quartzProperties" properties-ref="quartzCommonProperties"
            location="classpath:foo/bar/cfg/quartz-production.properties" />
  </beans>

  <beans profile="development">
      <util:properties id="quartzProperties" properties-ref="quartzCommonProperties"
            location="classpath:foo/bar/cfg/quartz-development.properties" />
  </beans>
</beans>

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 5, 2011

Stevo Slavić commented

This issue is related to #6201 and #9437

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 12, 2011

Chris Beams commented

As Juergen originally mentioned, the lack of merge support for collections has been a limitation of the util namespace from its inception. The real 'bug' here was with documentation, which Sam has since fixed. This is really an improvement request, and now marking it as such.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 16, 2011

Eric Haszlakiewicz commented

It sounds like this also needs a "parent" attribute like the regular bean element has, so you can specify what you're merging with. i.e.

<util:map id="map1">
    ...
</util:map>
<util:map id="map2" parent="map1" merge="true">
    ...
</util:map>

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 18, 2012

Matthew T. Adams commented

One thing that I'd like to make sure of in this request is that the ordering be controllable, in particular with maps. I'm commenting here as my issue, #13477, "Add MapCombiningFactoryBean", was resolved as a duplicate & Chris Beams just wanted to make sure that I got my $0.02 in WRT ordering. See https://jira.springsource.org/secure/attachment/19107/MapCombiningFactoryBean.java for more information.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Feb 1, 2016

Juergen Hoeller commented

At this point, I'm inclined to leave things as-is with respect to XML collection merging, since it only matters in combination with a feature of decreasing popularity: parent bean definitions. If there's a strong need for this appear in our XML configuration story in 2016 still, feel free to comment on this issue. If we don't hear about strong use cases in time for 4.3, we'll close the ticket for good.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants