I am trying to migrate an application from Jdeveloper 11g to 12c. I am using Java 8. I am getting following error:
org.apache.struts.validator.ValidatorForm ValidatorForm validate No >ValidatorAction named number found for field searchStnId
org.apache.commons.validator.ValidatorException: No ValidatorAction named >number found for field searchStnId
It is working on 11g, hence all the file entries viz. Validation.xml and entry in Struts-config.xml is there, and I am using struts-1.2.9.jar and Commons-Validator-1.1.3.jar. Can somebody give some suggestion to solve this ?
Code in Files is as follow :-
**/* _______________________________________________
**Validation.xml**
_______________________________________________*/**
<form name="searchForm">
<field property="searchValue" depends="required">
<arg key="prompt.searchStnValue"/>
</field>
<field property="searchStnId" depends="number">
<arg key="prompt.searchStnNumValue" />
</field>
</form>
**/* _______________________________________________
**Struts-config.xml**
_______________________________________________*/**
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/>
</plug-in>
**/* _______________________________________________
SearchForm.java
_______________________________________________*/**
public class SearchForm extends ValidatorForm
{
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
{
StationLog.debug("Class: SearchForm : Method : ActionForward validate() ");
String actionType = request.getParameter("actionType");
if("deleteStation".equals(actionType)) {
return new ActionErrors();
}
else if("stnId".equals(request.getParameter("searchCriteria")))
{
searchStnId = request.getParameter("searchValue");
searchStnId = searchStnId.trim();
StationLog.error("Class: SearchForm : Method: validate() :: stnId: "+searchStnId);
}
> return super.validate(mapping, request); //THIS IS THE LINE WHICH THROWS EXCEPTION
}
}
**/* _______________________________________________
ApplicationResources.properties
_______________________________________________*/**
prompt.searchStnValue = Search Value
prompt.searchStnNumValue = Entered Value
Related
I have a muddatagrid like this which has got the filters and i am able to filter it. Programmatically how can I get the filtered records?
<MudDataGrid Items="#Elements" #ref="dg" Filterable="true" FilterCaseSensitivity=DataGridFilterCaseSensitivity.CaseInsensitive>
<Columns>
<Column T="RequestInfo" Field="RequestId" Title="Request ID" />
<Column T="RequestInfo" Field="ProjectName" Title="Project Name" />
<Column T="RequestInfo" Field="RequestCreatedBy" Title="Created By" />
</Columns>
<NoRecordsContent>
<MudText>No matching records found</MudText>
</NoRecordsContent>
<PagerContent>
<MudDataGridPager T="RequestInfo" />
</PagerContent>
</MudDataGrid>
#code
{
MudDataGrid<RequestInfo> dg;
private async Task somefunction()
{
//this function is invoked after pressing a button in the page and all the filters have been applied.
List<RequestInfo> ll = dg.FilteredItems as List<RequestInfo>;
}
}
This function returns always 0 items. How Do I get to see only the filtered items programmatically?
dg.FilteredItems probably isn't a List when you apply filters. Instead of ... as List<RequestInfo>, call .ToList() on it:
#code
{
MudDataGrid<RequestInfo> dg;
private async Task somefunction()
{
List<RequestInfo> ll = dg.FilteredItems.ToList();
...
}
}
whats the difference between dg.FilteredItems.ToList(); and dg.FilteredItems as List;
The code:
dg.FilteredItems as List<RequestInfo>
is equivalent to:
dg.FilteredItems is List<RequestInfo>
? (List<RequestInfo>)dg.FilteredItems
: (List<RequestInfo>)null
This means that if the IEnumerable dg.FilteredItems is not a List, null will be returned.
The code:
dg.FilteredItems.ToList()
will return a new List, no matter what IEnumerable dg.FilteredItems behind the scenes is (an array, a IList, a ISet, ...)
I have a provider, wich index stock for product for every unit, this way:
for (Map.Entry<B2BUnitModel, Integer> unit : stockByUnit.entrySet() )
{
document.addField(indexedProperty, hasStock(unit.getValue()), unitUid(unit.getKey()));
}
so this is result after index in solr:
"localStockForUnt_001_boolean": true,
"localStockForUnt_002_boolean": true,
where localStockForUnt is SolrIndexedProperty, 001 and 002 are the units and true or false are the indexed value.
this is the impex to create it:
INSERT_UPDATE SolrIndexedProperty;solrIndexedType(identifier)`[unique=true];name[unique=true];type(code);sortableType(code);currency[default=false];localized[default=false];multiValue[default=false];useForSpellchecking[default=false];useForAutocomplete[default=false];fieldValueProvider;valueProviderParameter`
;$solrIndexedType; localStockForUnt ;boolean ; ; ; ; ; ; ;myResolver;
so I added it inside the 'sort' called 'relevance' in hmc, this 'sort' just have this field in hmc.
My doubt is, how can I set to it sort my result using for example localStockForUnt_002_boolean?
I did set sort in controller manually to test, I did set it to "relevance", but since the provider of field used in relevance (localStockForUnt) index two diferent informations, how can I select which one to use?
Actually what you are trying to do here was already been initiated and used in several cases by Hybris, for example:
localized properties like the name, indexed as name_en_string.
properties with currency like price is indexed as priceValue_eur_double and also used for Sort.
For :priceValue_eur_double | For : localStockForUnt_001_boolean.
priceValue is the field's name | localStockForUnt is the field's name.
euris the field qualifier | 001 is the field qualifier.
double is the field type | boolean is the field type.
So your case here is not different than these two examples, hence you need just to know how to use what's already exists.
Actually nothing magical about how these two examples works!
First of all, add new boolean attribute to SolrIndexedPropertyModel let's call it isB2bUnit :
<!-- add this to your *-items.xml -->
<itemtype code="SolrIndexedProperty" autocreate="false" generate="false">
<attributes>
<attribute qualifier="isB2bUnit" type="java.lang.boolean">
<persistence type="property" />
<!-- i would prefer to add a default value here : FALSE -->
</attribute>
</attributes>
</itemtype>
Next you have to add the same boolean attribute in the IndexedProperty dto :
<!-- add this to your *-beans.xml -->
<bean class="de.hybris.platform.solrfacetsearch.config.IndexedProperty">
<property name="isB2bUnit" type="boolean"/>
</bean>
Then you need to override DefaultIndexedPropertyPopulator it's the responsible for converting from SolrIndexedProperty to IndexedProperty:
public class MyIndexedPropertyPopulator extends DefaultIndexedPropertyPopulator {
#Override
public void populate(SolrIndexedPropertyModel source, IndexedProperty target) throws ConversionException {
super.populate(source, target);
//add this line
target.setIsB2bUnit(source.getIsB2bUnit());
}
}
Register the propulator into spring.
<!-- add this to your *-spring.xml -->
<alias name="myIndexedPropertyPopulator" alias="indexedPropertyPopulator" />
<bean id="myIndexedPropertyPopulator" class="com.foo.bar.MyIndexedPropertyPopulator" parent="defaultIndexedPropertyPopulator" />
The idea is to hook into this method DefaultFieldNameTranslator.translateFromProperty(...) and force it to add your specific fieldQualifier which is b2bUnit.code to the fieldName if the isB2bUnit of the Indexedproperty is TRUE.
The original DefaultFieldNameTranslator.translateFromProperty(...) is like this :
protected String translateFromProperty(SearchQuery searchQuery, IndexedProperty indexedProperty, FieldType fieldType) {
//...
if(qualifierProvider != null && qualifierProvider.canApply(indexedProperty)) {
Qualifier qualifier = qualifierProvider.getCurrentQualifier();
fieldQualifier = qualifier != null?qualifier.toFieldQualifier():null;
} else if(indexedProperty.isLocalized()) {
fieldQualifier = searchQuery.getLanguage();
} else if(indexedProperty.isCurrency()) {
fieldQualifier = searchQuery.getCurrency();
}
//you have to add your else if here!!!
return this.fieldNameProvider.getFieldName(indexedProperty, fieldQualifier, fieldType);
}
So create MyFieldNameTranslator that extends from DefaultFieldNameTranslator and override translateFromProperty(...).
Note: SomeB2bUnitService this service is not real but it should be able to return the current b2bUnit.
public class MyFieldNameTranslator extends DefaultFieldNameTranslator {
//To be injected!!
private SomeB2bUnitService someB2bUnitService;
#Override
protected String translateFromProperty(SearchQuery searchQuery, IndexedProperty indexedProperty, FieldType fieldType) {
//...
//...
else if(indexedProperty.getIsB2bUnit()) {
fieldQualifier = someB2bUnitService.getCurrentB2bUnit().getCode();
}
return this.fieldNameProvider.getFieldName(indexedProperty, fieldQualifier, fieldType);
}
}
Register the Translator into Spring :
<!-- add this to your *-spring.xml -->
<alias name="myfieldNameTranslator" alias="fieldNameTranslator" />
<bean id="myfieldNameTranslator" class="com.foo.bar.MyFieldNameTranslator" parent="defaultfieldNameTranslator">
<property name="someB2bUnitService" ref="someB2bUnitService" />
</bean>
Edit : now all what you have to do is to set isB2bUnit to true for localStockForUnt:
INSERT_UPDATE SolrIndexedProperty;solrIndexedType(identifier)[unique=true] ;name[unique=true] ;type(code) ;isB2bUnit
;$solrIndexedType ;localStockForUnt ;boolean ;true
Note : that some classes and beans may have been changed between Hybris versions but the concept will remains the same.
We have the following setup in our schema.xml:
<field name="last_modified" type="date" indexed="true" stored="true" multiValued="false" omitTermFreqAndPositions="true"/>
...
<field name="prefix" type="string" indexed="true" stored="true" omitTermFreqAndPositions="true"/>
Our goal is to sort the docs by
prefix=9999 with newest docs (last modified) first
prefix=1004 or prefix=1005 with newest docs (last modified) first
Our code:
{!boost b=recip(ms(NOW,last_modified),3.16e11,1,1)}prefix:9999^1000000 OR {!boost b=recip(ms(NOW,last_modified),3.16e-11,1,1)}prefix:1004^600000 OR {!boost b=recip(ms(NOW,last_modified),3.16e-11,1,1)}prefix:1005^600000
Result:
The query above does not work as expected!
We thought that omitTermFreqAndPositions=true will force to prevent ITF and the scoring should work. But it does not seem so!
Please help us with this :-)
So we found a solution!
Create your own Similarity (a simple java class)
For a better and simpler descriptions how, please read How to compile a custom similarity class for SOLR / Lucene using Eclipse
The class we used
package com.luxactive;
import org.apache.lucene.index.FieldInvertState;
import org.apache.lucene.search.similarities.DefaultSimilarity;
public class MyNewSimilarityClass extends DefaultSimilarity {
#Override
public float coord(int overlap, int maxOverlap) {
return 1.0f;
}
#Override
public float idf(long docFreq, long numDocs) {
return 1.0f;
}
#Override
public float lengthNorm(FieldInvertState arg0) {
return 1.0f;
}
#Override
public float tf(float freq) {
return 1.0f;
}
}
Create a simple jar with your Similarity
Copy the jar to any folder into your solr server, we used:
SOLRFOLDER/solr-4.8.0/example/solr/dih
The next steps need to be done to every collection you have!
Edit the solrconfig.xml at: SOLRFOLDER/solr-4.8.0/example/solr/collection/conf/solrconfig.xml
Add <lib dir="../dih" regex=".*\.jar" /> to import the custom jar
Edit the schema.xml in the same folder
Add the following
<!-- DEFAULT Factory for custom com.luxactive.MyNewSimilarityClass -->
<similarity class="solr.SchemaSimilarityFactory"/>
<!-- TYPE String -->
<fieldType name="no_term_frequency_string" class="solr.StrField" sortMissingLast="true" >
<similarity class="com.luxactive.MyNewSimilarityClass"/>
</fieldType>
<!-- TYPE Date -->
<fieldType name="no_term_frequency_date" class="solr.TrieDateField" sortMissingLast="true" >
<similarity class="com.luxactive.MyNewSimilarityClass"/>
</fieldType>
<!-- TYPE Int-->
<fieldType name="no_term_frequency_int" class="solr.TrieIntField" sortMissingLast="true" >
<similarity class="com.luxactive.MyNewSimilarityClass"/>
</fieldType>
Here you define your own field types (int, string and date) that use the new Similarity class which will return a boost value like defined in the MyNewSimilarityClass.
Now edit the fields you want to use your custom Similaritry by setting theyr type to one you created.
From: <field name="last_modified" type="date" indexed="true" stored="true" multiValued="false" />
To: <field name="last_modified" type="no_term_frequency_date" indexed="true" stored="true" multiValued="false" />
Restart the solr server and enjoy your boosting :)
I have a scalar-valued function in my sql database.
I receive this error when importing this function into Entity Framework model:
Error 6046: Unable to generate function import return type of the store function 'GetContentByIdAndCul'.
The store function will be ignored and the function import will not be generated. ..\EntityModels.edmx
my function tsql is:
ALTER FUNCTION [FRM].[GetContentByIdAndCul]
(#Id int,#Culture nvarchar(5))
RETURNS nvarchar(max)
AS
BEGIN
declare #Result nvarchar(max)
if #Id is not null
set #Result='This Content not defined in this Language'
select #Result=Value from CUL.Contents
WHERE ID=#Id AND (CUL.Contents.Culture = LOWER(#Culture)
OR CUL.Contents.Culture = LOWER(SUBSTRING(#Culture,1,2)))
return #Result
END
Preceding answers show the good way to solve the problem but none works in real life.
Here's a tested solution with Entity Framework 6 that works for me. So it should works for you.
Import your scalar valued function
Import your scalar valued function [FRM].[GetContentByIdAndCul] into your Entity Framework model. It automatically creates corresponding entry in the storage model of your EntityModels.edmx file :
<Function Name="GetContentByIdAndCul" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="FRM" ReturnType="nvarchar(max)">
<Parameter Name="Id" Type="int" Mode="In" />
<Parameter Name="Culture" Type="nvarchar(5)" Mode="In" />
</Function>
Add code to wrap call to your scalar valued function
Create new source file and add code to auto generated DbContext class (say her name is MyEntities) using Partial class mechanism (https://msdn.microsoft.com/en-us/library/wa80x488%28v=vs.120%29.aspx)
public partial class MyEntities
{
[DbFunction("EntityModels.Store", "GetContentByIdAndCul")]
public string GetContentByIdAndCul(int id, string culture)
{
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
var parameters = new List<ObjectParameter>();
parameters.Add(new ObjectParameter("Id", id));
parameters.Add(new ObjectParameter("Culture", culture));
return objectContext.CreateQuery<string>("EntityModels.Store.GetContentByIdAndCul(#Id, #Culture)", parameters.ToArray())
.Execute(MergeOption.NoTracking)
.FirstOrDefault();
}
}
Use your scalar valued function
Client code :
using (var context = new MyEntities())
{
int id = 1;
string culture = "fr-FR";
string result = null;
result = context.GetContentByIdAndCul(id, culture);
}
Until today, entity framework doesn't suport generating calls for scalar functions.
But, you can solve the problem writting a custom method like this inside your DbContext class:
public partial class YouDbContext
{
[DbFunction("YouDbContext.Store", "YourScalarFunction")]
public string YourScalarFunction(string parameter)
{
var lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
return lObjectContext.
CreateQuery<string >(
"YouDbContext.Store.YourScalarFunction",
new ObjectParameter("parameterName", parameter)).
Execute(MergeOption.NoTracking).
FirstOrDefault();
}
}
Create a partial class for YOURMODEL.Context.cs: public partial class YOUREntities : DbContext
[DbFunction("YOURModel.Store", "YOURSCALARFUNCTION")]
public string YOURSCALARFUNCTION(string PARAMETER)
{
List<ObjectParameter> parameters = new List<ObjectParameter>(3);
parameters.Add(new ObjectParameter("PARAMETER", PARAMETER));
var lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
var output = lObjectContext.
CreateQuery<string>("YOURMODEL.Store.YOURSCALARFUNCTION(#PARAMETER)", parameters.ToArray())
.Execute(MergeOption.NoTracking)
.FirstOrDefault();
return output;
}
Be sure that you have your function added to YOURMODEL.EDMX, should be some thing like this:
<Function Name="YOURSCALARFUNCTION" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" ReturnType="nvarchar(max)">
<Parameter Name="PARAMETER" Type="nvarchar(max)" Mode="In" />
</Function>
I've got class, let it be Foo:
public class Foo
{
...
protected MyCollection<Detail> _details
public virtual MyCollection<Detail> Details
{
get { return _details ?? new MyCollection<Details>(); }
set { _details = value; ... }
}
...
}
public class Detail {...}
When I do LINQ query:
var q = session.Query<Foo>().Select(foo => new Foo( property1 = foo.property1, ... );
...
q.ToList();
I've got NULL in _details field, and when I access to Details to get all Lazy details, of course I get new MyCollection(), but not IPersistentBag (or else, IPersistentCollection).
So How can I manually create proxy collection (I've got session / sessionFactory references)?
[ Added ] here is the mappings (on Foo):
<bag name="Details" lazy="true" collection-type="NHibernateDataService.DetailBag`1[[DataObjects.Detail, DataObjects]], NHibernateDataService" cascade="all-delete-orphan" fetch="select" batch-size="1" access="property" inverse="true">
<key column="`Master`" />
<one-to-many class="DataObjects.Detail" />
</bag>
Thank you!
MyCollection can't be mapped to IPersistentBag, unless, of course, you implement that interface on MyCollection (and probably set the mapping type explicitly??)...
A more standard approach is to set the "collection-type" property on the bag mapping to a custom type - an implementation of IUserCollectionType, which you can choose to make a base class that MyCollection derives from.