spring mongodb not saving newly added field - spring

this is my mongo db document
classA {
private String name;
private long elapsedTime; // newly added field
}
#Document
classB extends classA{
private String id;
private String owner;
}
classBRepository.save(classBObject);
but newly added elapsedTime field is not saved to database, others are saved. if I call save method second time then that field is saved.
I am not using any strict schema configuration by the way.
What do you think that can cause this problem ? is it because of some configuration, is there anything I am missing here ?
MongoDb version: 5.0.6
Spring version: 2.6.6

Related

Spring Data Persist entity in Log Table before each save()

im working in a spring boot project and i have a requirement to save the old object in a specific table before each new save ; this my man entities:
#Entity
#Table(name="demande")
public class Demande {
#Id
private Long id;
// all properties
}
#Entity
#Table(name="demande_log")
public class DemandeLog {
#Id
private Long id;
// all properties
}
what im trying to do is before each demandeRepository.save(demande);
i want to save the old demande object (current row in database) as DemandeLog in my demande_log table.
do you have any idea how using spring data, i know that there is a listener #PrePersist in JPA.. but i want to do it properly.
Regards.
I recommend using Envers. It is easy to set up and gives you a complete change log.

Spring mongo InvalidPersistentPropertyPath with #Version

I was migrating from spring boot 2.0.0 to 2.1.1. After migrating one of the several issues that I am facing is the InvalidPersistentPropertyPath for documents with certain fields and #version. This used to work previuosly with Spring boot 2.0.0
Below is the sample document that I want to save in mongo db:
#Document
#Data
#NoArgsConstructor
public class Report implements Serializable {
#Id
protected String id;
#NotNull
#Field("ReportName")
protected String reportName;
#Field("IA1Value")
private Long iA1Value = 0L;
#Field("IA2Value")
private Long iA2Value = 0L;
#Version
private Long version;
public Report(String reportName) {
this.reportName = reportName;
}
}
I wrote a test case to read and save to the mongo DB.
org.springframework.data.mapping.context.InvalidPersistentPropertyPath:
No property 'IA1Value' found on class
com.experiments.migration.mongo.Report! Did you mean:
IA2Value,IA1Value,iA2Value,iA1Value?
But if the #Version is commented it works....
I would like to know what the relation is with #Version.
The entire sample is there in :
https://github.com/KencyK/spring-boot-migration
NOTE : Please DO NOT suggest to keep the field name. Coz i know that would fix it. I would like to know why this works if I remove the #Version.
Also I have tried with older version of Lombok which was used in spring boot 2.0.0

How do I get Spring's Data Rest Repository to retrieve data by its name instead of its id

I am using Spring Data's Rest Repositories from spring-boot-starter-data-rest, with Couchbase being used as the underlining DBMS.
My Pojo for the object is setup as so.
#Document
public class Item{
#Id #GeneratedValue(strategy = UNIQUE)
private String id;
#NotNull
private String name;
//other items and getters and setters here
}
And say the Item has an id of "xxx-xxx-xxx-xxx" and name of "testItem".
Problem is, that when I want to access the item, I need to be accessible by /items/testItem, but instead it is accessible by /items/xxx-xxx-xxx-xxx.
How do I get use its name instead of its generated id, to get the data.
I found out the answer to my own question.
I just need to override the config for the EntityLookup.
#Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withEntityLookup().forRepository(UserRepository.class).
withIdMapping(User::getUsername).
withLookup(UserRepository::findByUsername);
}
}
Found the info here, though the method name changed slightly.
https://github.com/spring-projects/spring-data-examples/tree/master/rest/uri-customization
If you want query the item by name and want it perform as querying by id,you should make sure the name is unique too.You cant identify a explicit object by name if all objects have a same name,right?
With jpa you could do it like:
#NotNull
#Column(name="name",nullable=false,unique=true)
private String name;

Spring MongoDB Save

I'm creating a Spring Boot application and I am using AngularJS on the frontend.
Upon submitting a form with the appropiate parameters, Spring is supposed to use bookRepository.save() method in order to save the provided data in the MongoDB. The problem is, this action gets carried on, but the structure of my model is not respected.
#Document(collection = "books")
public class Book {
private String id;
private String title;
private String author;
private String description;
private String cover;
// Getters and setters below.
}
The final outcome after following the above process: instead of having a record following the above structure inserted in MongoDB, I only end up with a field containing _id and _class.
Any ideas as to why is this happening?

Spring Data Redis Repository support does not read back embedded complex objects

I have a spring-boot application (1.4RC1, I know it's RC, but Spring Data Redis 1.7.2 is not) where I'm using spring-boot-starter-redis.
The application uses a Spring Data Repository (CrudRepository) which should save an object (using #RedisHash annotation) with String and Boolean properties and one custom class property, which also has only Strings and Longs as properties.
When I save an object (via the repository), everything went fine and I can see all the properties in the database as I would expect.
When I want to read the data from the database (via the repository) I only get the properties from the parent object. The custom class property is null.
I would expect to get the property loaded from the database as well. As the documentation states you can write a custom converter, but since I don't need to do that, when I want to write the data, I shouldn't need to write a reading converter as well.
I wonder if I need to annotate the custom class property, but I couldn't find anything in the documentation. Can you point me in the right direction?
The classes are as follows:
Class sample:
#Data
#EqualsAndHashCode(exclude = {"isActive", "sampleCreated", "sampleConfiguration"})
#RedisHash
public class Sample {
#Id
private String sampleIdentifier;
private Boolean isActive;
private Date sampleCreated;
private SampleConfiguration sampleConfiguration;
public Sample(String sampleIdentifier, SampleConfiguration sampleConfiguration){
this.sampleIdentifier = sampleIdentifier;
this.sampleConfiguration = sampleConfiguration;
}
}
Class SampleConfiguration:
#Data
public class SampleConfiguration {
private String surveyURL;
private Long blockingTime;
private String invitationTitle;
private String invitationText;
private String participateButtonText;
private String doNotParticipateButtonText;
private String optOutButtonText;
private Long frequencyCappingThreshold;
private Long optOutBlockingTime;
}
I added #NoArgsConstructor to my Sample class as Christoph Strobl suggested. Then the repository reads the SampleConfiguration correctly. Thanks, Christoph!

Resources