I need to use property "similarity" in my elasticsearch index, but cannot find the property in the Field annotation of Springframework. It seems, the Springframework Elasticsearch library don't have that. Do I need to use another library or are there simple ways to do that? Can you recommend a library or a way?
You can use the Setting annotation and define your settings in a separate file, with the appropriate configuration for similarity.
To perform this, just add #Setting(settingPath = "/path/to/settings.json") to your index class, where you have #Document annotation.
e.g.
#Setting(settingPath = "/path/to/settings.json")
#Document(indexName = "indexName")
public class IndexClass {
#Id
private String id;
private String name;
// getters and setters
}
And your settings.json should look like :
"index": {
"similarity": {
"my_similarity": {
"type": "DFR",
"basic_model": "g",
"after_effect": "l",
"normalization": "h2",
"normalization.h2.c": "3.0"
}
}
}
And you can find more in the documentation.
Related
I am working in a legacy system with Java/EJB/JPA/thorntail/wildfly.
The project has:
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>jaxrs-jsonb</artifactId>
<version>2.6.0.Final</version>
</dependency>
JSON-B provides support for JSON Processing according to JSR-367.
I need to send null values in API/Rest. Anything similar to #JsonInclude(Include.ALWAYS) for Jackson.
Example that I need:
PersonApi with name=Any, age=null
{
"name": "Any",
"age": null
}
Is there some config to do this? ... some annotation, some config to load and resolve it?
You can use javax.json.bind.annotation.JsonbNillable annotation:
#JsonbNillable
public static class PersonApi {
private String name;
private Integer age;
//constructors, getters and setters are omitted
}
I'm trying to use Spring Data Rest to implement a full set of services for about 60 entities. Right now, I'm getting by with just letting Spring use my repositories rather than implementing controllers, which is great!
The data I'm having to model isn't ideal--I'd prefer to have customerId come as part of the order object.
{
"tenantId": 42,
"id": "00000001",
"customer": {
"tenantId": 42,
"id": "CUST001",
"name": "Arthur Dent"
}
}
I have the ID for a related entity as a property on my JSON object.
public class Order {
Long tenantId;
String id;
String customerId;
}
I don't really want to pull the full Customer entity and all of the other related entities and place them as members on my Order object. Instead, I'd just like to add some links to the _links collection.
I believe I've figured out WebMvcLinkBuilder finally and I have the basic idea in place. However, JpaRepository.findById returns a java.util.Optional.
#Bean
public RepresentationModelProcessor<EntityModel<Order>> orderProcessor() {
return new RepresentationModelProcessor<EntityModel<Order>>() {
#Override
public EntityModel<Order> process(final EntityModel<Order> model) {
final CustomerRepository controller = WebMvcLinkBuilder.methodOn(CustomerRepository);
final CustomerId id = new CustomerId(model.getContent().getTenantId(), model.getContent().getCustomerId());
model.add(WebMvcLinkBuilder.linkTo(controller.findById(id)).withRel("customer"));
return model;
}
};
}
The error I get is:
Could not generate CGLIB subclass of class java.util.Optional: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class java.util.Optional
How can I add a link to my resource?
I want to expand configuration metadata in my project just as mentioned in the documentation.
Usually, I can use the spring-boot-configuration-processor dependency to generate my own metadata. But in this case, I'm using Map<String, Foo> properties in my properties, and I want the IDE to show code hints when using these propertie.
Let me show you the code.
FooProperties
#ConfigurationProperteis("server.worker")
public class FooProperties {
private int workerCount;
private int subWorkerCount;
private int limit;
#NestedConfigurationProperty
private Map<String, BooProperties> group = new HashMap<>();
//getter and setter
}
BooProperties
public class BooProperties{
private int workerCount;
}
additional-spring-configuration-metadata.json
{
"properties":[{
"name": "server.worker.group",
"type":"java.util.Map<java.lang.String,com.FooProperties>",
"description": ".....",
"sourceType":"com.FooProperties"
}],
"hints":[{
"name":"server.worker.group.keys",
"providers":[{
"name":"any"
}]
}, {
"name":"server.worker.group.values",
"providers" : [{
"name":"class-reference"
}]
}]
}
And this is an image of my IDE, not showing any hints:
Is there anything I can change to make this work?
I found the problem.
In my code, I annotated #Import and #Autowird on FooProperties.
When I remove those annotations and use the 'spring-boot-configuration-processor' dependency, It works.
So, that case can work fine.
I am working with a project that is generated with jhipster. It is a micro service architecture project.
In my entity class properties are named with camel case. So when I create a rest service it gives me json, where the json property names are as same as the entity properties.
Entity class
#Entity
#Table(name = "ebook")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "ebook")
public class Ebook implements Serializable {
private Long id;
private String nameBangla;
private String nameEnglish;
Json response
{
"id": 0,
"nameBangla": "string",
"nameEnglish": "string"
}
I want that my entity property will camel case, But in json response it will snake case. That is I don't want to change my entity class but I want to change my json response like bellow
{
"id": 0,
"name_bangla": "string",
"name_english": "string"
}
You have two possibilities:
Explicit naming your properties:
#JsonProperty("name_bangla")
private String nameBangla;
#JsonProperty("name_english")
private String nameEnglish;
or changing how jackson (which is used for de/serialization) works:
Jackson has a setting called PropertyNamingStrategy.SNAKE_CASE
which you can set for the jackson objectmapper.
So, you need to configure Jackson for that, e.g. by adding your own object mapper:
#Configuration
public class JacksonConfiguration {
#Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder().propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
}
}
As far as I know, in older version of JHipster, there was already a JacksonConfiguration to configure the JSR310 time module, but was removed later...
Adding this to your application.yml should also work:
spring.jackson.property-naming-strategy=SNAKE_CASE
Also you can use annotation to define naming strategy per class.
Little example in Kotlin:
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class)
data class Specialization(val altUrl: String, val altId: Int, val altName: String)
How do you implement in Jackson a conversion from json to Java objects, based on class types specified in the json.
Example Java Types:
public class Car{
public String make;
public String model;
}
public class Spoon {
public String material;
}
public class Ownership {
public List<Object> items;
public User owner;
}
Example Json:
{
"items": [
{
"#class": "com.example.Car",
"make": "Mercedes-Benz",
"model": "S500"
},
{
"#class": "com.example.Spoon",
"material": "silver"
}
],
"owner": {
"name": "John"
}
}
Since the number of classes is unknown (users can add any class) it is not possible to use the annotation #JsonSubTypes.
In addition, the json may contain known strongly types classes, like the object User in the example which is serialized using the standard Jackson implementation.
Most of the examples I can find, such as http://www.baeldung.com/jackson-inheritance assume the number of subclasses is known, but in my case it is not, users of the framework will add their own.
Ideally the implementation will just resolve types and let Jackson do the rest of the serialization without repeating that code.
Can be solved using an annotation on the collection:
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.PROPERTY,
property = "#class")
public List<Object> items;