#Version is not being incremented in Spring mongo - java

I have added
#Enableauditng as an annotation but #version is not incrementing the version on its own.
I have #LastModifiedDate, which is being updated but not the #version.
Am i doing somehting wrong.
I am calling mongoTemplate.save(object) to againg and again.
Please advice

I think you are using:
javax.persistence.Version
Check your imports, #Version is part of javax.persistence (JPA) and has no relation to mongodb.
http://docs.spring.io/spring-data/mongodb/docs/1.5.0.RELEASE/reference/htmlsingle/
Unluckily, there is no hint to #Version in the spring data mongodb reference.
You should import org.springframework.data.annotation.Version for entity version information. See https://github.com/spring-projects/spring-data-mongodb/blob/1.5.x/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithVersionPropertyOfTypeInteger.java

Make sure your "entity" class is a #org.springframework.data.mongodb.core.mapping.Document
and not a
#javax.persistence.Entity
Then, also make sure you're using:
#org.springframework.data.annotation.Id
and
#org.springframework.data.annotation.Version

Related

Optimistic Locking in Hibernate does not change the value of the version-column in the table

To implement optimistic locking in Spring Boot project, I added a field with the #Version annotation:
package com.example.my_api.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name = "clients")
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Client {
// ...
#Version
private Integer version;
// ...
}
Then i added a version-column in the corresponding table, using Liqubase-migration:
And now, I'm testing with Postman. First I create a new client with a POST-request, then I update its data (name, age) with a PUT-request. If I understand correctly, when we update the entity, it should automatically increase the value of the version-field by 1. But in my case this does not happen:
The value is 0 and it is not incremented. Can you help me? What i do wrong?
Accepted answer from this similar question: How to increase a version field on save in Hibernate regardless if dirty or not?
You can use Hibernate interceptors to update the version number of the
master record when you identify that detail has changed.
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/events.html
One limitation is that this solution is specific to Hibernate. JPA
also allows event-driven logic using annotations (e.g. PostPersist,
PostUpdate, etc...) but these methods don't give you access to the
underlying session (and, more importantly, the documentation cautions
you from using these methods to modify session data). I've typically
used interceptors to perform auditing, but they could easily be
extended to update a version number when a record is altered.
I had a similar issue, and mine was because the data was not flushed to the database prior to the second DML.
To test, i changed my repository and extends JpaRepository instead of extends CrudRepository. Then instead of doing save, i did saveAndFlush. My version field was updated as expected.

Can we increment version of MongoDB document version manually in Spring Data MongoDB?

We can use versionType = EXTERNAL, EXTERNAL_GTE in ElasticSearch entities to manage version of entity and #Version annotated field will be incremented manually by developer in spring-data-elasticsearch.
So, when we send any document update which has smaller version then VersionConflictEngineException will be thrown but it will let you send any version which greater then or equal(in EXTERNAL_GTE case) the current entity version.
Is there any chance to manage version of mongoDB documents in that way in spring-data-mongodb?
According to the documentation, you can use the #Version annotation. Be aware that the class I'm refering to is: org.springframework.data.annotation.Version, not the JPA one.

The type Entity is deprecated in Eclipse [duplicate]

I am attempting to update to Hibernate 4 and I am getting that org.hibernate.annotations.Entity is deprecated. None of the documentation however seems to indicate that this is the case. Anyone have any insight into this?
#org.hibernate.annotations.Entity(dynamicUpdate = true)
Yes it is deprecated in 4.0+:
Deprecate org.hibernate.annotations.Entity
Its individual attributes/values should become annotations.
Schedule for removal in 4.1
You should use #DynamicUpdate instead
Here is a fixed JIRA talking about it.
From Hibernate Getting Started Guide :
The #javax.persistence.Entity annotation is used to mark a class as
an entity. It functions the same as the class mapping element
discussed in Section 2.3, "The mapping file". Additionally the
#javax.persistence.Table annotation explicitly specifies the table
name. Without this specification, the default table name would be
EVENT).
Since org.hibernate.annotations.Entity has been deprecated you should use the Java EE annotation. Also, as tolitius already mentioned, for the annotation configurations of #org.hibernate.annotations.Entity, you should use the respective annotation, e.g. #DynamicUpdate.
Hope that helps.
Note: Event is the name of the class that is annotated in the example, this is why it states "default table name would be EVENT".
Use the JPA #Entity annotation instead of the Hibernate #Entity annotation. Look in your imports, it should say
import javax.persistence.Entity;
and not
import org.hibernate.annotations.Entity;
For future purpose, please refer the deprecated API list for Hibernate 4.0. The link is as follows:-
Deprecated API

org.hibernate.annotations.Entity deprecated in Hibernate 4?

I am attempting to update to Hibernate 4 and I am getting that org.hibernate.annotations.Entity is deprecated. None of the documentation however seems to indicate that this is the case. Anyone have any insight into this?
#org.hibernate.annotations.Entity(dynamicUpdate = true)
Yes it is deprecated in 4.0+:
Deprecate org.hibernate.annotations.Entity
Its individual attributes/values should become annotations.
Schedule for removal in 4.1
You should use #DynamicUpdate instead
Here is a fixed JIRA talking about it.
From Hibernate Getting Started Guide :
The #javax.persistence.Entity annotation is used to mark a class as
an entity. It functions the same as the class mapping element
discussed in Section 2.3, "The mapping file". Additionally the
#javax.persistence.Table annotation explicitly specifies the table
name. Without this specification, the default table name would be
EVENT).
Since org.hibernate.annotations.Entity has been deprecated you should use the Java EE annotation. Also, as tolitius already mentioned, for the annotation configurations of #org.hibernate.annotations.Entity, you should use the respective annotation, e.g. #DynamicUpdate.
Hope that helps.
Note: Event is the name of the class that is annotated in the example, this is why it states "default table name would be EVENT".
Use the JPA #Entity annotation instead of the Hibernate #Entity annotation. Look in your imports, it should say
import javax.persistence.Entity;
and not
import org.hibernate.annotations.Entity;
For future purpose, please refer the deprecated API list for Hibernate 4.0. The link is as follows:-
Deprecated API

org.hibernate.AnnotationException: #OneToOne or #ManyToOne on <entity> references an unknown entity

I am receiving the following Hibernate Exception:
org.hibernate.AnnotationException: #OneToOne or #ManyToOne on cz.rohan.dusps.model.Switchport.konfiguracniTemplateAccess references an unknown entity: cz.rohan.dusps.model.KonfiguracniTemplate
org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:103)
org.hibernate.cfg.AnnotationConfiguration.processEndOfQueue(AnnotationConfiguration.java:541)
org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:523)
org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:380)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1377)
org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
cz.rohan.dusps.helper.SessionFactoryHelper.initFactory(SessionFactoryHelper.java:122)
cz.rohan.dusps.helper.SessionFactoryHelper.getSessionFactory(SessionFactoryHelper.java:134)
cz.rohan.dusps.filter.HistorieZmenFilter.doFilter(HistorieZmenFilter.java:102)
cz.rohan.dusps.filter.CharsetFilter.doFilter(CharsetFilter.java:41)
after ~20 hours spent on the problem with various people, having read every possible blog or forum, I am really getting desperate here.
This is a mid-sized project. I should mention the database is Postgres 9.1 and we generate the DB using a modelling tool. Hibernate connects to the database but does not generate it.
I have created a new entity in the database, it's called "KonfiguracniTemplate" (configuration template). I have created the model, controller, form, validators, .jsp's, all basically copied 1:1 from an existing entity of a similar nature. I can now work with KonfiguracniTemplate, CRUD is fully working.
The problem comes when I reference this KonfiguracniTemplate from the entity called Switchport. In the DB there is a relation between the two:
Switchport 1:1 ... 0:N KonfiguracniTemplate (switchport always references a KonfiguracniTemplate; a KonfiguracniTemplate MAY BE referenced zero or more times)
Switchport has FK konfiguracniTemplateAccess_id for this relation.
In .../model/Switchport.java the relation is mapped just like all other relations that are working:
#ManyToOne
#JoinColumn(nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
I have tried various forms:
#ManyToOne
#JoinColumn(name="konfiguracnitemplateaccess_id", nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
or
#ManyToOne(targetEntity=KonfiguracniTemplate.class)
#JoinColumn(name="konfiguracnitemplateaccess_id", nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
I have also checked:
both entities are in the same package
they are both annotated "#Entity" using "import javax.persistence.Entity;"
the build produces no error/warning messages
as long as the reference in Switchport is commented out, everything is fine
No matter what I try I cannot get rid of the "references an unknown entity" exception. Can somebody please share an idea what is happening or maybe how to debug the issue? The stacktrace at the top of the post is all I get in the logs.
All input is greatly appreciated!
Just add the class Team to the "hibernate-cfg.xml" file, because Hibernate doesn't identify without adding into it.
Possible Solutions:
1) Ensure that the entity has been appropriately referenced in hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
...
<mapping class="com.project.entitytwo.model.EntityTwo"/>
...
</session-factory>
2) Ensure that #Entity has been specified at the class-level ( at the top of the class )
#Entity
#Table( name="ENTITY_TWO" )
public class EntityTwo extends AnyClass
{
...
I just had this problem, with entity a referencing entity b. Both entities were located in a common JAR outside of the web project I was working on; a was declared in persistence.xml but b wasn't. I put b in a <class> tag in persistence.xml and it worked!
I ran into this problem when using Spring and not using the hibernate.cfg.xml file. It was solved by adding the fully qualified package name of the Model class to the setPackagesToScan method of LocalSessionFactoryBean class.
Finally got the solution from another developer on the team!
The classes need to be imported before the SessionFactory object is created. Here the import for the new class was missing, so it was unknown to the SessionFactory object.
Anyway, thanks everyone for your hints!
There is one more chance of getting such exception; when you don't mention your mapping class in hibernate.cfg.xml file.
As mentioned above.
I had same exception... I just forget add annotation (#Entity, and #Table) on MASTER class(class with Primary key)
so solution is double check every annotation in your entities , I mean not only #ManyToOne and #OneToMany like i did.
if your two entity in diffrent project,you can scan KonfiguracniTemplate's package in other project.you can do like this in spring boot
#EntityScan({"com.thispackage.entity","com.KonfiguracniTemplatepackage.entity"})
I'll give you a solution that should work for the same error with Spring Boot. This has less to do with the original question, but today, people would probably look for this answer instead because noone uses XML configuration today anymore.
I suffered the same problem and found the solution on this website: https://www.programmersought.com/article/1617314625/
He even describes this very question he would have looked up, but then I'm asking myself: why didn't he answered here after finding the solution? LOL
His own words:
In the Spring Boot project, the default scan package is the package where the main method is located, that is, only the entity classes in the same package as the main method will be discovered. This way you can understand why User is not found: because User is an entity class in another module. Spring Boot does not scan other packages at all;
Configure the #SpringBootApplication annotation on the main method that launches the application, telling Spring Boot that those packages need to be scanned: #SpringBootApplication(scanBasePackages = {“com.xiaomo.*”})
Then, User can be found.
So you basically reconfigure SpringBoot to scan more packages to include the other ones.
My personal addition: you could also move your packages into the package where the starter is located or move the starter a package up (that's what I did).

Categories

Resources