History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: IDEADEV-23354
Type: New Feature New Feature
Status: Open Open
Priority: Normal Normal
Assignee: Dmitry Avdeev
Reporter: Tom Adams
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
IDEA: Development

Generate bean does not support inner beans

Created: 19 Nov 07 02:06   Updated: 20 Nov 07 05:14
Component/s: J2EE.Spring
Fix Version/s: None

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
Environment:
Linux hill 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT 2007 i686 GNU/Linux

Build: 7,364
Severity: Medium


 Description  « Hide
Generate bean fails when

To reproduce:

1. Go into spring wiring file.
2. Create bean, add constructor args, position cursor within constructor args, see below:

<bean class="com.vlc.kahuna.ws.translate.ReachReportRequestElementToAudienceQueryParametersTranslator">
    <constructor-arg index="1">
            <!-- position cursor here, press Alt-Insert (Ctrl-enter) -->
    </constructor-arg>
    <constructor-arg index="2">
        <bean class="com.vlc.kahuna.ws.translate.ElementToDemographicTranslator"/>
    </constructor-arg>
</bean>

3. Hit Alt-Insert (Ctrl-Enter on Mac)
4. Select "Spring Bean"
5. Get code as follows:

<bean class="com.vlc.kahuna.ws.translate.ReachReportRequestElementToAudienceQueryParametersTranslator">
    <constructor-arg index="1">

    </constructor-arg>
    <constructor-arg index="2">
        <bean class="com.vlc.kahuna.ws.translate.ElementToDemographicTranslator"/>
    </constructor-arg>
</bean>
<bean id="" class="">
        
</bean>

Code should look like:

<bean class="com.vlc.kahuna.ws.translate.ReachReportRequestElementToAudienceQueryParametersTranslator">
    <constructor-arg index="1">
        <bean id="" class="">
        
        </bean>
    </constructor-arg>
    <constructor-arg index="2">
        <bean class="com.vlc.kahuna.ws.translate.ElementToDemographicTranslator"/>
    </constructor-arg>
</bean>

As an aside, spring bean creation shouldn't default to adding an id attribute to each element. Adding IDs to beans is verbose and usually unnecessary.



 All   Comments   Work Log   Change History      Sort Order:
Taras Tielkes - 19 Nov 07 17:11
I agree, generate...bean should be able to generate inner beans. Also, I agree that for inner beans it should not ask for id.

Tom, do you think that generate...bean should by default ask for id for a top-level bean, or not?


Tom Adams - 20 Nov 07 01:22
Hi,

No, I don't believe it should ask for an ID on top-level beans, but then again I'm not your average spring user. I try to avoid IDs when possible and make heavy use of auto-wiring, which the spring documentation suggests you avoid (I don't agree with their reasoning). I feel that IDs are noise in the XML file, they're mostly used for cross-referencing within the wiring XML file (say bean B has a dependency on bean A) and never used in code for resolving instances. Auto-wiring can take care of most of the need for bean cross-referencing, and when you do need it, spring uses the class name as the ID anyway, so you can always reference it by the class (which admittedly is a little long).

While I do find the fact that IDEA assumes I want an ID annoying (one of the reasons that I like IDEA is that it doesn't force me to work a different way), you may want to ask some typical spring users, who use IDs for their opinion. There's nothing stopping them from adding it back in, and IDEA does a pretty good job of guessing bean IDs when you want them.

Tom


Taras Tielkes - 20 Nov 07 02:24
Indeed, in practice there are two styles of usage, I guess:
  • autowire everything (a la PicoContainer), and only use explicit names to resolve ambiguities
  • use names everywhere (probably more typical for the average spring user)

There are valid arguments for both sides. I don't have a strong preference myself.
However, in larger projects it's a good idea to pick one and be consistent.

Generate...bean should indeed support inner beans, and leave out "id" for those. That's clear.
I'm not sure about leaving out "id" for top-level beans - however I do see your point.

Two questions for you:

  • if generate...bean would only insert <bean class="..."/>, is that still worth a separate template action? If not - can you think of other ways to make generate...bean more useful?
  • generally speaking, does IDEA support your "auto-wiring driven" style of configuration well?

Tom Adams - 20 Nov 07 05:14
Hey,

Thanks for being so prompt. I'll attempt to answer both your questions at once

I think the generate bean is still useful even without an id. It saves me typing the XML by hand (IDEA has had broken closing XML tag behaviour since the 6.0 release), and it's a good sanity check to make sure that you're allowed to insert a bean in the current position in the file. It also auto-generates reasonable bean IDs, so they're easy to add after the fact. Also, you can use the camel case functionality to complete the bean class very easily. I suppose you could add this as a live template, then people could change it? Ah, I see that it is, I will remove the ID from it to satisfy our needs.

You could go further and allow Alt-Enter style intentions on beans, some that I can think of:

  • Add ID, use the bean name
  • Fill in constructor params - add appropriate <constructor-arg index="2"> or <property name="schema" value="foo.xsd"/> to the bean. IDEA already knows about the classes and what constructor args and setters they expose (it detects errors for example), so this sort of thing wouldn't be too hard.
  • Move bean from upper-level to inner bean.
  • Move bean from inner bean to upper-level.

In regard to the "auto-wiring driven" style, once I added a bean, if IDEA did a better job of automatically locating and inserting dependencies - going from the code and inserting into the XML, rather than from the XML and changing the code as it currently does - it would be nice. So if you select "generate bean", you enter the type name it could automatically fill out constructor args as either a reference to a bean or an inner bean that would be great. You could look up the beans already defined and offer to create a reference, and for those constructor args where there was no bean in scope, you could offer to create an inner bean, or create an upper-level bean for the type.

In general though, the spring integration is very nice. We're also playing around with using AspectJ to define point cuts for timing code, and it is very nice there also (though a little flaky - it doesn't always find advised methods in the right-hand gutter for example).