Spring.net - PropertyRetrievingFactoryObject - property is null - inversion-of-control

In an attempt to resolve this question, I'm taking a look at how our spring.net configuration works.
The root problem comes from this snippet:
<object name="someObject" singleton="false" type="SomeType.someObject, SomeAssembly">
<constructor-arg name="authSession">
<object type="Spring.Objects.Factory.Config.PropertyRetrievingFactoryObject, Spring.Core">
<property name="TargetObject" ref="AuthSessionManager" />
<property name="TargetProperty" value="CurrentAuthSession" />
</object>
</constructor-arg>
</object>
In a case where a user is not logged in, AuthSessionManager.CurrentAuthSession will be null. When that is the case, Spring.NET throws an exception: "Factory object returned null object".
How can I tell Spring that the null object is acceptable in this case?

You can use an expression to retrieve an object from the spring context in your constructor argument, something like:
<object name="someObject" singleton="false"
type="SomeType.someObject, SomeAssembly">
<constructor-arg name="authSession"
expression="#(AuthSessionManager).CurrentAuthSession" />
</object>
Expressions are allowed to evaluate to null, so you don't have to tell Spring anything.
This worked for me in a simple case (no nested contexts).

Related

cxf jax-ws no complexType for subclasses while using generic method

I am not quite familiar with CXF configuration. Here I am encountering a situation that a object (subclass) is going to be used for client but it does not declare in Endpoint.
For example, there is a super class "SuperClass" and two subclasses "SubClassA" and "SubClassB". The following method is declared in Endpoint:
public <T extends SuperClass> T search(Criteria criteria, ClassType type);
Therefore, those subclasses do not appear in Endpoint and it causes that their complexType is missing in wsdl. Error saying no read type is prompted when the object of subclass is called from client.
org.apache.cxf.interceptor.Fault:
Could not determine how to read type: {http://model.fmchan.com}SubClassA
So here I would like to seek for a solution to add those subclasses into wsdl so as to be called properly on client side.
If it is properly configured, the following should be shown on wsdl:
<xsd:complexType name="SubClassA">
<xsd:sequence>
<xsd:element minOccurs="0" name="date" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
Enclosed is the configuration on server side for your reference.
<import resource="classpath:META-INF/cxf/cxf.xml" />
<bean id="aegisContext" class="org.apache.cxf.aegis.AegisContext"
p:writeXsiTypes="true" scope="prototype" />
<bean id="aegisBean" p:aegisContext-ref="aegisContext"
class="org.apache.cxf.aegis.databinding.AegisDatabinding"
scope="prototype" />
<bean id="genericServiceImpl" class="com.fmchan.service.SomeEndpointImpl"/>
<jaxws:endpoint implementor="#genericServiceImpl"
address="${service.address}">
<jaxws:serviceFactory>
<ref bean="jaxws-and-aegis-service-factory" />
</jaxws:serviceFactory>
</jaxws:endpoint>
<bean id="jaxws-and-aegis-service-factory"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
scope="prototype">
<property name="dataBinding">
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</property>
</bean>
Thank you for any help in advance.
The simplest solution I come up with is to create a dummy method including those subclasses A and B as parameters for endpoint. It probably isn't the best solution and I still seek for better one.

Understanding CQ5 Lucene indexing rule

Information:
I have provided an indexing configuration file to cq5. I have not indexed on the property cq:template by specifying the following rule:
<index-rule nodeType="nt:base">
<property nodeScopeIndex="false">cq:template</property>
</index-rule>
I rebuilt the index.The logs show re-indexing is properly done.
The problem I am facing:
When I execute the following SQL2 query, it gives me the same results as it would give without the above indexing rule:
SELECT s.[cq:template] FROM [nt:base] AS s WHERE s.[cq:template] like '/apps/geometrixx/templates/contentpage'
Your rule actually omits all properties from the index except for cq:template rule (and excludes cq:template from the fulltext index because you defined nodeScopeIndex="false"). See the jackrabbit documentation for more details.
When you define the element <property nodeScopeIndex="false">cq:template</property>, the system includes the property in the index. However, nodeScopeIndex="false" tells CRX/Jackrabbit not to include the property in the fulltext index. Meaning it would be available for all searches except for those using contains(...) in sql or jcr:contains(...) for xpath.
To avoid indexing a property entirely, omit it from the first index-rule with nodeType/condition attributes that match its node. It must be the first matching rule because the rules in index_config.xml file are processed top down.
So to remove the cq:template property from the index in CQ5, do the following:
Extract the out of the box CQ5 version of indexing_config.xml (See this documentation for instructions)
Remove the <property nodeScopeIndex="false">cq:tempate</property> from <index-rule nodeType="nt:base">
Change the regular expression in the last rule <property isRegexp="true"> from .*:.* to ^(?!cq:template).*:.*$:
After you make the changes, the index-rule should look like this:
<index-rule nodeType="nt:base">
<property nodeScopeIndex="false">analyticsProvider</property>
<property nodeScopeIndex="false">analyticsSnippet</property>
<property nodeScopeIndex="false">hideInNav</property>
<property nodeScopeIndex="false">offTime</property>
<property nodeScopeIndex="false">onTime</property>
<property nodeScopeIndex="false">cq:allowedTemplates</property>
<property nodeScopeIndex="false">cq:childrenOrder</property>
<property nodeScopeIndex="false">cq:cugEnabled</property>
<property nodeScopeIndex="false">cq:cugPrincipals</property>
<property nodeScopeIndex="false">cq:cugRealm</property>
<property nodeScopeIndex="false">cq:designPath</property>
<property nodeScopeIndex="false">cq:isCancelledForChildren</property>
<property nodeScopeIndex="false">cq:isDeep</property>
<property nodeScopeIndex="false">cq:lastModified</property>
<property nodeScopeIndex="false">cq:lastModifiedBy</property>
<property nodeScopeIndex="false">cq:lastPublished</property>
<property nodeScopeIndex="false">cq:lastPublishedBy</property>
<property nodeScopeIndex="false">cq:lastReplicated</property>
<property nodeScopeIndex="false">cq:lastReplicatedBy</property>
<property nodeScopeIndex="false">cq:lastReplicationAction</property>
<property nodeScopeIndex="false">cq:lastReplicationStatus</property>
<property nodeScopeIndex="false">cq:lastRolledout</property>
<property nodeScopeIndex="false">cq:lastRolledoutBy</property>
<property nodeScopeIndex="false">cq:name</property>
<property nodeScopeIndex="false">cq:parentPath</property>
<property nodeScopeIndex="false">cq:segments</property>
<property nodeScopeIndex="false">cq:siblingOrder</property>
<property nodeScopeIndex="false">cq:template</property>
<property nodeScopeIndex="false">cq:trigger</property>
<property nodeScopeIndex="false">cq:versionComment</property>
<property nodeScopeIndex="false">jcr:createdBy</property>
<property nodeScopeIndex="false">jcr:lastModifiedBy</property>
<property nodeScopeIndex="false">sling:alias</property>
<property nodeScopeIndex="false">sling:resourceType</property>
<property nodeScopeIndex="false">sling:vanityPath</property>
<property isRegexp="true">^(?!cq:template).*:.*$</property>
</index-rule>
Note of warning:
I'm not sure if it is safe to remove cq:template from the search index as the product code may use it in some way. As a best practice, it is recommended to only exclude custom application properties. Also, you must include properties in the fulltext index which contain references to other content paths. This is because when you move a page in CQ5 (AEM) then it does a jcr:contains search to see where that page is referenced. So if you exclude such properties with nodeScopeIndex="false" or by modifying the regular expression above to omit them then the reference search will fail. Then you end up with stale references to old paths.
References:
Official indexing_config.xml reference: http://wiki.apache.org/jackrabbit/IndexingConfiguration
Instructions on how to update indexing_config.xml in CQ5: http://helpx.adobe.com/experience-manager/kb/SearchIndexingConfig.html

Is it possible to assign default values to NAnt properties?

I'd like to use the property value as a part of an argument passed to a certain EXE via <exec/> task. There's a condition which influences the property initialization, that is, if condition is true, it should contain value, otherwise be just empty (but still defined).
This is what I ended up so far:
<property name="prop1" value="" />
<property name="prop1" value="some-value-based-on-condition" if="condition-goes-here" />
And later on:
<exec program="my.exe">
<arg value="C:\Root\Folder\${prop1}" />
...
</exec>
If the property is not set, I'd like to pass just C:\Root\Folder\ as an argument value.
Initializing the property in this way seems too much for such a simple operation. Is there a way to do it simpler using what's in NAnt at the moment? I would imagine something like:
<property name="prop1" value="somevalue-based-on-condition" if="condition" default="" />
The example below should meet your needs. It will create a property named 'SolutionConfiguration' and assign it the value 'Release' if and only if the same parameter isn't already defined (ie. it was defined via the command line).
<property name="SolutionConfiguration" value="Release" unless="${property::exists('SolutionConfiguration')}" />
For your scenario, try
<property name="RootFolder" value="c:\Root\Folder" unless="${property::exists('RootFolder')}" />
<exec program="my.exe">
<arg value="${RootFolder}\${prop1}" />
...
</exec>
Use overwrite="False"
<property name="RootFolder" value="c:\Root\Folder" overwrite="false" />

In Entity Framework, getting the value of an identity column after inserting

I'm using EF4. I want to insert a new MyObject into the database. MyObject has two fields:
Id: int (Identity) and
Name: string
As I've seen in documentation Entity Framework is supposed to set MyObject.Id to the value generated by database after the call to SaveChanges() but in my case that doesn't happen.
using (var context = new MyEntities())
{
var myObject = MyObjects.CreateMyObject(0, "something"); // The first parameter is identity "Id"
context.MyObjects.AddObject(myObject);
context.SaveChanges();
return myObject.Id; // The returned value is 0
}
UPDATE:
This happens in one of my entities and others work fine. By the way, I checked and the DB column is identity and StoreGeneratedPattern is set to Identity.
Here is the SSDL. I don't see any difference. The first one isn't working right:
<EntityType Name="OrgUnit">
<Key>
<PropertyRef Name="Srl" />
</Key>
<Property Name="Srl" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="TypeId" Type="smallint" Nullable="false" />
<Property Name="Name" Type="varchar" Nullable="false" MaxLength="80" />
</EntityType>
<EntityType Name="OrgType">
<Key>
<PropertyRef Name="Srl" />
</Key>
<Property Name="Srl" Type="smallint" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Title" Type="varchar" Nullable="false" MaxLength="120" />
<Property Name="Options" Type="int" Nullable="false" />
</EntityType>
The update is done successfully in the database and the identity is generated but the entity object is not updated with the new identity.
In that case, you EF model is probably not up to date - EF should automagically get your new ID from the database. Try refreshing your EF model.
Your identity column's properties should look like this in your EDMX model:
If you're using Oracle Entity Framework 4 Provider, like I do, from ODP.NET, there is a bug in Designer. Just selecting the Identity value in drop down box will not do. It will annotate the conceptual property in conceptual model with
annotation:StoreGeneratedPattern="Identity"
like in
<Property Type="Int32" Name="Id" Nullable="false" cg:SetterAccess="Private" annotation:StoreGeneratedPattern="Identity" />
But, it will fail to do the same for Storage Model, ie. you need to do it manually. Find the Property (in my case ID) in EntityType of interest and add StoreGeneratedPattern="Identity".
<EntityType Name="PROBLEMI">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="number" Nullable="false" Precision="10" StoreGeneratedPattern="Identity" />
I'm not aware of the same bug in SQL EF provider 'cos I didn't use it.
This should "just work." Make sure the DB column actually is IDENTITY, and that StoreGeneratedPattern is set to Identity in EDMX.
wow! that was a nightmare but at last I solved it, although I didn't understand what the problem was. Maybe this helps someone with the same problem.
Generate the script for creating the table and its data.
Drop the table.
Run the script.
If you are using Linq To Entities, and get this error even if you followed the advices of marc_s (that are really good), you should look at your entites directly in the edmx (xml view) and check if they have the following attribute :
<EntityType Name="MyEntity">
<Key>
<PropertyRef Name="pk" />
</Key>
<Property Name="pk" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="value" Type="float" Nullable="false" />
</EntityType>
The StoreGeneratedPattern="Identity" is also required.
Try using refresh method after Save Changes, it has been documented in MSDN
"To ensure that objects on the client have been updated by data source-side logic, you can call the Refresh method with the StoreWins value after you call SaveChanges."
http://msdn.microsoft.com/en-us/library/bb336792.aspx
Though i feel what #Craig has suggested might also work.
I ran into this today. The difference though was I was using an insert function, where the above person doesn't specify that. What I had to do was make my insert function stored procedure return SCOPE_IDENTITY() and use a result binding for the id returned.
Fixed my issue.

Property Inject an Array with Spring.Net

I've been using the Spring.Net IoC container and can use it to inject properties that are of type IList and even IList<T> but I'm a bit stumped as to how to inject a property thats of type string[].
There doesn't seem to be an <array> element defined in the XSD's and using <list> <value> </list> doesn't work either.
If anyone could post the xml I need to inject using an array for a property it'd be much appreciated
As mentioned here in the documentation you can inject a string array as a comma delimited string (not sure what the syntax is for escaping actual commas in strings if necessary). In other words your config would look something like this:
<object id="MyObject" type="Blah.SomeClass, Blah" >
<property name="StringArrayProperty" value="abc,def,ghi" />
</object>
Manually constructing a string[] with the following syntax also works, if you need something more complex (for example if you're looking the individual values up from some other reference rather than hard coding them):
<object id="TestStrArr" type="string[]" >
<constructor-arg value="3" />
<property name="[0]" value="qwe" />
<property name="[1]" value="asd" />
<property name="[2]" value="zxc" />
</object>
<object id="MyObject" type="Blah.SomeClass, Blah" >
<property name="StringArrayProperty" ref="TestStrArr" />
</object>