I've a question regarding the configuration of Hibernate Search via persistence.xml . The standard analyzer used for indexing and searching is the StandardAnalyzer. This analyzer has a list of english stopwords per default. I know that via constructor this stopword-list can be replaced with an own list (or EMPTY_SET). Unfortunately I didn't find such an option in the official documentation. The only thing I found is that it's possible to set a different analyzer via the hibernate.search.analyzer property. My question: is there an existing property to deactivate the english stopwords while using the StandardAnalyzer?
You could define your own subclass of StandardAnalyzer, pass the parameters you want to the super constructor, and set the hibernate.search.analyzer property to the fully qualified classname of your subclass. EDIT: As #AnarchoEnte replied, StandardAnalyzer is a final class, so you actually cannot do that.
But in my opinion, you'd be better off defining your own analyzer doing exactly what the standard analyzer does, but without stopwords:
#AnalyzerDef(
name = "myDefault",
tokenizer = #TokenizerDef(
factory = org.apache.lucene.analysis.standard.StandardTokenizerFactory.class
),
filters = {
#TokenFilterDef(
factory = org.apache.lucene.analysis.standard.StandardFilterFactory.class
),
#TokenFilterDef(
factory = org.apache.lucene.analysis.core.LowerCaseFilterFactory.class
)
}
)
public class MyEntity { // The annotation must be on an indexed entity, which one doesn't matter.
...
}
Then set it as default analyzer:
hibernate.search.analyzer = myDefault
This way, if you ever need to change something to the analyzer (add some filters, change the tokenizer, ...) you will only have to change that definition.
Related
I'm looking for a simple solution to an ugly problem. I am using Spring Data JPA and have 7 entities that are all related. I have a need to do a findByEntity1_NameAndEntity2_NameAndEntity3_NameAndEntity4_NameAndEntity5_NameAndEntity6_NameAndEntity7_Name
I need every permutation including and excluding each other those entities. I could build all 128 methods and use a big case statement to select which one to use, but that's horridly ugly. I feel like I'm missing the easy button on this one.
Query By Example method
I think the best option for you is to use the (imo, somewhat infrequently used) QueryByExample feature of Spring Data JPA. On researching this answer, I posted an answer somewhere else that needed the same response. I'd take a look at that to get an idea of how this solves your problem.
You'll first need to the QueryByExampleExecutor to your Repository.
Secondly you'll just need to create your query like so (and hopefully you're using fluent builders for your entities!):
ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject()
.withEntity1(new Entity1().withName("foo"), matcher);
repository.findAll(exampleQuery);
Would select all of the MyObject elements with Entity1 having name of foo.
ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues();
Example<MyObject> exampleQuery = Example.of(new MyObject()
.withEntity1(new Entity1().withName("foo"),
.withEntity2(new Entity2().withName("bar"),
.withEntity3(new Entity3().withName("baz"),
.withEntity4(new Entity4().withName("foo"),
.withEntity5(new Entity5().withName("bar"),
.withEntity6(new Entity6().withName("baz"),
.withEntity7(new Entity7().withName("foo")
), matcher);
repository.findAll(exampleQuery);
Would select all of the MyObject elements for Entity1 with name of foo, Entity2, with name of bar, etc.
I am using spring caching in my project using annotations. Based on profile I am using Elasticache and SimpleCacheManager. The annotations used are
//For the initial configuration settings in some class when profile is cloud.
#EnableElastiCache({#CacheClusterConfig(name = "MyCache", expiration = 86400)})
// For the initial configuration settings in some class when profile is non-cloud.
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
simpleCacheManager.setCaches(newArrayList(new ConcurrentMapCache("MyCache")));
#CacheConfig(cacheNames = {"MyCache"})
public class CachingRequiredClass{
........
#Cacheable
public String blablaMethod(String id){
.....
}
}
public class SomeOtherClass{
......
#Caching(evict={
#CacheEvict(value="MyCache", key="T(com.myclass).myMethod()+':blablaMethod()'"),
#CacheEvict(value="MyCache", key="T(com.myclass).myMethod()+':blablaMethod()+':blablabla2Method()'")
})
public void logout(){
......
}
}
I am forced to hard code cache name "MyCache" everywhere which I dont like. Is there a way to make this configurable. Somehow coming from a property file??
You have several options.
First of all, it is Java so you can create a constant somewhere and refer to it. Then those places allow for SpEL so you can write ${myCache} and have a myCache property in the environment that has the value of your cache.
Finally, rather than specifying the cache names in code (be it using SpEL or not) you can implement CacheResolver and decide which cache to use programmatically. It's more work and probably overkill if you don't need to change the cache to use according to some business logic.
Part of the smell it annoys you is that you are maybe using the same cache for too many things. That key attribute in your last example looks mental to me: if you need to add the name of the class and the method to the key, it tells me you're trying to put way too many things in the same cache. You shouldn't design your cache like that: do not forget it is just a shortcut so that you don't have to do this manually. If you want to query the cache for a value, are you seriously going to use the name of the class and the method to compute the key?
I have an simple object that has a name
public class Foo {
private String name
}
Each user on the site may have up to 10 Foo's associated with them. Within this context, when a new Foo is created, I would like to validate that there isn't another foo associated with the same user that already exists.
I could Create a custom Bean Validator But annotations require the paramaeters to be defined during compilation. How would I then pass across the names of the existing Foos?
As suggested in various places, I could use EL expressions as an alternative way to pick up the data. This feels like using a sledgehammer to crack a nut. It also brings in a whole bunch of potential issues to consider least of all being ease of testing.
I could do class-wide validation using a boolean field
#AssertTrue(message="Name already exists")
public boolean isNameUnique() {
return (existingNames.contains(name));
}
But the validation message would not show up next to the name field. It is a cosmetic issue and this can be a backup plan. However, its not ideal.
Which brings me to the question:
Is there a simple way to write a Bean Validator that can check the value against a collection of values at the field level and meet the following restrictions ?
Previous values determined at runtime
Not using things like EL expressions
Field level validation instead of class level.
EDIT in reponse to Hardy:
The Foo class is an entity persisted within a database. They are picked up and used through a DAO interface.
I could loop through the entities but that means plugging the DAO into the validator and not to mention that the I would need to write the same thing again if I have another class that too has this constraint.
It would help to see how you want to use the Foo class. Can you extend your example code? Are they kept in a list of Foo instances. A custom constraint seems to be a good fit. Why do you need to pass any parameters to the constraints. I would just iterate over the foos and check whether the names are unique.
I use contructor injection in my solution, but this one class has a property that i do not want to pass in the constructor where i have the invariant dependencies.
Let's say i got an ILogger and it has a FileName property i want to set, while still having it set the dependancies in the contructor.
How do i go about registering the type, and at the same time pass the defaunt connection string.
I hope there is an easy way to do it - preferably without decorating the property with an attribute, but if the setup is easier with the attribute i guess that's cool :)
So the question is, how do i inject a property value on an object that also uses contructor injection - with Unity.
UPDATE: I mentioned it in the title, but i forgot to elaborate in the body of the text - i want to set these dependencies up manually (in code) as opposed to in a config file.
Ok i guess it helped to ask the question, i found out - here it is.
container.Configure<InjectedMembers>().ConfigureInjectionFor<BasicLogger>(
new InjectionProperty("FileName", #"C:\test.log")
);
If you are injecting properties you have to use [Dependency] or else manually inject that dependency.
You usually want an IConfiguration interface to be injected. This would probably have a LogFile property that you can read.
The Configuration implimentation is usually just a simple wrapper to read items from the config file.
I'd like to generate method-chaining setters (setters that return the object being set), like so:
public MyObject setField (Object value) {
this.field = value;
return this;
}
This makes it easier to do one-liner instantiations, which I find easier to read:
myMethod (new MyObject ().setField (someValue).setOtherField (someOtherValue));
Can Eclipse's templates be modified to do this? I've changed the content to include return this; but the signature is not changed.
I confirm eclipse (up to 3.5RC1) does not support "method chaining" setter generation.
It only allows for comment and body customization, not API modification of a setter (meaning a generated setter still return 'void').
May be the plugin Builder Pattern can help here... (not tested though)
Classic way (not "goof" since it will always generate a "void" as return type for setter):
(source: eclipse.org)
Vs. new way (Builder Pattern, potentially used as an Eclipse plugin)
alt text http://www.javadesign.info/media/blogs/JDesign/DesignConcepts/DesignPatterns/GOF/Creational-BuilderPatternStructure.jpeg
Don't use eclipse myself, but you'll have to change one of the standard templates if you can't find a feature.
It's called method chaining by the way (which might help with a Google search or two).