In the service.xmlfile added the following finder Method
<finder name=”City” return-type=”Collection”>
<finder-column name=”city”></finder-column>
</finder>
Ran the ant target “ant build-service”
In the SampleUtil.java, Copied the finder method from this class and paste it inside the SampleLocalServiceImplclass and modify the method definition
public static java.util.List<com.sample.model.Sample> findByCity(
java.lang.String city) throws com.liferay.portal.SystemException {
return SampleUtil.findByCity(city);
}
Ran the target “ant build-service” again.
But the finder is avialable in SampleLocalServiceUtil, until i restrated the Machine .
Please let me know , why is that so ?? Or am i missing something .
Thanks
List<Sample> customerList = SampleLocalServiceUtil.findByCity(“cityname”);
To use the "finder" I would use the instance of the persistence class available to you in the LocalService.
To extend your example,
Instead of SampleUtil.findByCity(city), do samplePersistence.findByCity(city).
samplePersistence will already be created for you by the base implementation of SampleLocalServiceImpl.java.
Related
I have created a custom mapper class as below but ABP does not automatically register and use it while mapping.
https://docs.abp.io/en/abp/4.4/Object-To-Object-Mapping#iobjectmapper-tsource-tdestination-interface
Sorry for less detail, i have added some below,
I have found that mycustommapperclass's interface different from my object mapper,
should I implement for all container types?
public class HierachyItemCustomMapper : IObjectMapper<HierachyItem, HierachyItemDto>, ITransientDependency
{
and my usage like
var nodeListDto = ObjectMapper.Map<IEnumerable<HierachyItem>, IEnumerable<HierachyItemDto>>(nodeList);
How can i handle this?
Obviously I am looking for a result instead of foreach iterator loop.
Edit:
it have found that it is known issue as below
https://github.com/abpframework/abp/issues/94
I've tried just before and it seems it works as expected.
This is my HierachyItemCustomMapper class which I've created in the Application layer. (It should be created in the Application layer.)
public class HierachyItemCustomMapper : IObjectMapper<HierachyItem, HierachyItemDto>, ITransientDependency
{
public HierachyItemDto Map(HierachyItem source)
{
return new HierachyItemDto
{
Name = source.Name
};
}
public HierachyItemDto Map(HierachyItem source, HierachyItemDto destination)
{
destination.Name = source.Name;
return destination;
}
}
I've just added a property named Name in my both classes (HierachyItem and HierachyItemDto) to test.
You probably didn't define it in the Application layer and that cause the problem. Can you check it?
It's simple , your defination is wrong
it should be like that
public class HierachyItemCustomMapper : IObjectMapper<IEnumerable<HierachyItem>,
IEnumerable<HierachyItemDto>>, ITransientDependency {}
as it searches for exact defination match , and if you want to add also capability of using ObjectMapper.Map<HierachyItem, HierachyItemDto>
you can make your custom mapper defination like that
public class HierachyItemCustomMapper : IObjectMapper<IEnumerable<HierachyItem>,
IEnumerable<HierachyItemDto>>, IObjectMapper<HierachyItem, HierachyItemDto> ,
ITransientDependency {}
and you will implement both
good luck
With Spring Integration 4.2.0, it mentioned that 'filter' and 'locker' must be present if custom Scanner is being used (https://jira.spring.io/browse/INT-3619).
I don't know how to set this with XML config if I simply override the listEligibleFiles() method and use the default filters provided by DefaultDirectoryScanner.
e.g.
// using the default filters
public class MyDirectoryScanner extends DefaultDirectoryScanner {
#Override
protected File[] listEligibleFiles(File directory) throws IllegalArgumentException {
return super.listEligibleFiles(directory);
}
}
<bean id="myCustomScanner"
class="com.company.MyDirectoryScanner" />
<int-file:inbound-channel-adapter directory="my_directory"
prevent-duplicates="true"
scanner="myCustomScanner"
channel="myChannel">
<int:poller fixed-rate="10"
time-unit="SECONDS" max-messages-per-poll="5" />
</int-file:inbound-channel-adapter>
It's not clear what you mean; that JIRA was to fix a bug where those properties were incorrectly overridden.
When injecting a custom scanner, you need to set those properties on your scanner rather than via the namespace.
use the default filters provided by DefaultDirectoryScanner.
The DefaultDirectoryScanner has the code:
public DefaultDirectoryScanner() {
final List<FileListFilter<File>> defaultFilters = new ArrayList<FileListFilter<File>>(2);
defaultFilters.add(new IgnoreHiddenFileListFilter());
defaultFilters.add(new AcceptOnceFileListFilter<File>());
this.filter = new CompositeFileListFilter<File>(defaultFilters);
}
So, if you would like do not use AcceptOnceFileListFilter (or any other default) you should follow with the recommendation from the Docs and use setFilter() of the DirectoryScanner contract. For this purpose there is FileListFilterFactoryBean with the setPreventDuplicates() to be set to false.
And yes, remove, please, prevent-duplicates="true" from your configuration, because it is prohibited, when scanner is in use:
Assert.state(!(this.scannerExplicitlySet && (this.filter != null || this.locker != null)),
"The 'filter' and 'locker' options must be present on the provided external 'scanner': "
+ this.scanner);
The filter can be set to null on the DefaultDirectoryScanner by the way...
I'm converting the JIRA to Documentation just to be more clear on the matter.
I have created an interface which two different services are implementing.
Consider interface is named as CheckReference and two different classes CheckReferenceImpl1 and CheckReferencImpl2 are implementing it.
#Component
#Service(value = CheckReference.class)
#Property(name = "domain", value = "ref1")
public class CheckReferenceImpl1 implements CheckReference
And another one,
#Component
#Service(value = CheckReference.class)
#Property(name = "domain", value = "ref2")
public class CheckReferenceImpl2 implements CheckReference
Now I want to dynamically load the implementation depending on my need using #Reference annotation dynamically.
So , In a check condition
public class LoadReference {
#Reference
CheckReference checkReference
if(check) {
// load checkReferencImpl1
} else {
// load checkReferenceImpl2
}
}
Also I know that I can use target property to load specific implemenation. But that is static way.
But in order to do this dynamically , Not able to relate from specifications and tutorials how should I do this ??
First, you have to make LoadReference a #Component, so that it is managed by the SCR (otherwise #Reference won't work either). Next, you have to provide a configuration for it using the Configuration Admin Service. In this configuration, you can provide a filter for the reference by providing a property with the name REFERENCE_NAME.target:
checkReference.target = FILTER_EXPRESSION
FILTER_EXPRESSION is a standard LDAP-expression used in OSGi-filters. Due to property propagation, this configuration property will be propagated to the service-component, and it will be used when selecting a target service for checkReference. This does not require any code for checking the condition in LoadReference.
Have you looked at ComponentContext.locateService?
I'm trying to re-use some of the model configurations on several entities that implements a interface.
Check this code:
public static void ConfigureAsAuditable<T>(this EntityTypeConfiguration<T> thisRef)
where T : class, IAuditable
{
thisRef.Property(x => x.CreatedOn)
.HasColumnName("utctimestamp")
.IsRequired();
thisRef.Property(x => x.LastUpdate)
.HasColumnName("utclastchanged")
.IsRequired();
} // ConfigureAsAuditable
as you can see I'm trying to call the extension method "ConfigureAsAuditable" on my onmodelcreating method like this:
EntityTypeConfiguration<Account> conf = null;
conf = modelBuilder.Entity<Account>();
conf.ToTable("dbo.taccount");
conf.ConfigureAsAuditable();
When debugging i get this exception:
The property 'CreatedOn' is not a declared property on type
'Account'. Verify that the property has not been explicitly excluded
from the model by using the Ignore method or NotMappedAttribute data
annotation. Make sure that it is a valid primitive property.
Thanks in advance :)
PD:
I'm using EF 5-rc, VS 2011 and .NET Framework 4.5
I think a better approach would be to implement your own derived version of EntityTypeConfiguration. For example:
public class MyAuditableConfigurationEntityType<T> : EntityTypeConfiguration<T>
where T : class, IAuditable{
public bool IsAuditable{get;set;}
}
Then, when building your model, use that new type:
var accountConfiguration = new MyAuditableConfigurationEntityType<Account>();
accountConfiguration.IsAuditable = true; // or whatever you need to set
accountConfiguration.(HasKey/Ignore/ToTable/Whatever)
modelBuilder.Configurations.Add(accountConfiguration);
I'm trying to override the getDescriptiveName() method in com.liferay.portal.model.Group
I found a wrapper (com.liferay.portal.model.GroupWrapper), so I tried to write a hook as written in the documentation :
liferay-hook.xml:
<service>
<service-type>com.liferay.portal.model.GroupWrapper</service-type>
<service-impl>fr.villedeniort.hook.expando.GroupWrapperImpl</service-impl>
</service>
fr.villedeniort.hook.expando.GroupWrapperImpl.java:
public class GroupWrapperImpl extends GroupWrapper {
public GroupWrapperImpl(Group group) {
super(group);
}
#Override
public java.lang.String getDescriptiveName()
throws com.liferay.portal.kernel.exception.PortalException,
com.liferay.portal.kernel.exception.SystemException {
return super.getDescriptiveName();
}
When the hook is deployed, it raises an exception :
java.lang.NoSuchMethodException: fr.villedeniort.hook.expando.GroupWrapperImpl.<init>(com.liferay.portal.model.GroupWrapper)
I browse the code I found out that it breaks at this part for a reason I ignore:
Constructor<?> serviceImplConstructor = serviceImplClass.getConstructor(new Class<?>[] {serviceTypeClass});
At this point, variables have theses values:
serviceType "com.liferay.portal.model.GroupWrapper" (id=14829)
serviceImpl "fr.villedeniort.hook.expando.GroupWrapperImpl" (id=14830)
serviceTypeClass Class<T> (com.liferay.portal.model.GroupWrapper) (id=14831)
serviceImplClass Class<T> (fr.villedeniort.hook.expando.GroupWrapperImpl) (id=14832)
Do you have any idea?
Thanks!
You should have also a constructor without any argument. Now you have one with constuctor arguments, but there is no pure class constructor that java searches when it makes class instance. After calling the pure constructor java then calls the argumented one.
I had similar case in some other context and this was the solution. <init> tag on the error message refers on this kind of issue.
Apparently, it's not possible to hook other classes than Services, so I had to find a different way. For my case, I hooked a JSP and wrote my own method to get the right descriptive name from the hook.