javers MANAGED_CLASS_MAPPING_ERROR - java

I did a refactoring and now my class B is not an Entity anymore but a Value.
If I try viewing the diff of an already audited Entity A, that contains a list of B's I am getting this exception: JaversException MANAGED_CLASS_MAPPING_ERROR: given javaClass 'class B' is mapped to ValueType, expected EntityType
Is there a recommended way how to fix this?

Sadly, looks like there is no workaround other than manually deleting snapshots of previous Entity.
I have created the issue for this case https://github.com/javers/javers/issues/753

Related

Hibernate native SQL query - how to get distinct root entities with eagerly initialized one-to-many association

I have two entities Dept and Emp (real case changed and minimized). There is 1:n association between them, i.e. properties Dept.empList and Emp.dept exist with respective annotations. I want to get List<Dept> whose elements are distinct and have collection empList eagerly initialized, using native SQL query.
session.createSQLQuery("select {d.*}, {e.*} from dept d join emp e on d.id = e.dept_id")
.addEntity("d", Dept.class)
.addJoin("e", "d.empList")
//.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
This query returns List<Object[2]> with instances of Dept, Emp (in that order) in the array and field Dept.empList properly initialized. That's ok.
To get distinct Depts, I thought setting transformer DISTINCT_ROOT_ENTITY (uncommenting the line) would be enough. Unfortunately, the DistinctRootEntityResultTransformer is based on RootEntityResultTransformer which treats the last element in tuple as root entity (it's hardwired). Since the order of entities is determined by sequence of addEntity, addJoin calls, the transformer mistakenly treats Emp as root entity and returns list with all Emps of all Depts.
Is there any clean way how to make Hibernate recognized the Dept as root entity, even though it is not last in entity list?
Note 1: I tried to switch order to .addJoin("e", "d.empList").addEntity("d", Dept.class). Does not work since d.empList requires d defined. Fails on HibernateSystemException : Could not determine fetch owner somewhere in Hibernate internals (org.hibernate.loader.Loader).
Note 2: I tried to define order as .addEntity("e", Emp.class).addJoin("d", "e.dept"). This seemingly works but the association is actually filled only from the "many" side. Hence the collection Dept.empList is some uninitialized proxy until requested, which invokes explicit SQL query and thus does not utilize the join in my query.
Note 3: The custom transformer looking for hard-wired index works:
.setResultTransformer(new BasicTransformerAdapter() {
public Object transformTuple(Object[] tuple, String[] aliases) {
return tuple[0];
}
public List transformList(List list) {
return DistinctResultTransformer.INSTANCE.transformList( list );
}
})
though I'm hesitant to accept such easy task could have such complicated solution.
Hibernate version: 3.6.10 (I know - legacy project :-) though I looked into source code of latest version and seems the key points don't differ).
Finally found https://stackoverflow.com/a/17210746/653539 - make duplicate call of .addEntity to force root entity on the end of list:
.addEntity("d", Dept.class)
.addJoin("e", "d.empList")
.addEntity("d", Dept.class)
It's still workaround but cleaner than mine and - based on 36 upvotes - it seems as idiomatic solution.

Configuring JaVers ID for third party objects

I'm trying to use JaVers to store objects from a 3rd-party library that I can't change. The object definition looks something like:
interface TheirObject extends WithId{
//Other properties here...
}
interface WithId{
String getId();
}
with various implementations of that interface. The ID field is not annotated in anyway.
I tried using the default JaVers configuration and got the following error:
JaversException MANAGED_CLASS_MAPPING_ERROR: given javaClass 'interface TheirObject' is mapped to ValueObjectType, expected EntityType
So I configured JaVers as follows:
javers = JaversBuilder.javers()
.registerEntity(new EntityDefinition(TheirObject.class))
.build();
Which gives the exception:
JaversException ENTITY_WITHOUT_ID: Class 'TheirObject' mapped as Entity has no Id property. Use #Id annotation to mark unique and not-null Entity identifier
So I tried telling it about the id field:
javers = JaversBuilder.javers()
.withMappingStyle(MappingStyle.BEAN)
.registerEntity(new EntityDefinition(TheirObject.class, "id"))
.build();
Which gives the exception:
JaversException PROPERTY_NOT_FOUND: Property 'id' not found in class 'TheirObject'. If the name is correct - check annotations. Properties with #DiffIgnore or #Transient are not visible for JaVers.
I've tried a few different variations of id (e.g. Id, getId) but nothing seems to work and I haven't found the documentation very useful in working out how to proceed.
Could someone please help me configure JaVers properly so I can use it to track changes to these objects? Thanks.
Update: I've changed the interface above to better reflect the issue, as I'd over-simplified it to a point where my examples did actually work.
JaversBuilder.javers()
.registerEntity(new EntityDefinition(TheirObject.class, "id"))
.build();

No Such Method error in HQL

I'm getting following error
java.lang.NoSuchMethodError: org.hibernate.hql.antlr.HqlBaseParser.recover(Lantlr/RecognitionException;Lantlr/collections/impl/BitSet;)V
org.hibernate.hql.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1173)
org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:702)
org.hibernate.hql.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:296)
org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:159)
org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:248)
when execute the following hql
select object(o),p.dateApply,p.reason,p.Approver from Person as o "+
" com.jpa.entities.Application as p where o.id = p.nricNo and o.batchNumber= :batchNo
if i remove the following query
p.dateApply,p.reason,p.Approver
it's working just fine. The thing i want is to return value from both Person entities and Application entities.
Hope somebody can assist me as I'm new to HQL.
It sounds like you've got either incompatible Hibernate-related JARs, or duplicates of some or all of those JARs. Perhaps because you upgraded to a different version of Hibernate without deleting the old JARs (or something similar).
If different versions of the class com.my.MyClass are found in both lib1.jar and lib2.jar and the classloader loads MyClass from lib1.jar, but the "correct" MyClass (the one with the method the JRE is looking for) is found in lib2.jar, you'll experience exactly the problem you're seeing.

JPA EntityManager with Hibernate - find and remove does not delete data from database

Having trouble getting the following code to work...
I've got a JpaTransactionManager txManager autowired into this test. I know record with ID 39 does exist. It still exists at the end of the transactions, too...
TransactionStatus status = txManager.getTransaction(def);
A a = mock(A.class);
when(a.getId()).thenReturn(Long.valueOf(39));
sut.delete(a);
txManager.commit(status);
status = txManager.getTransaction(def);
a = sut.get(a.getId());
txManager.commit(status);
assertNull(a);
Code in class A:
public void delete(A a) {
a = getEntityManager().find(A.class, a.getId());
getEntityManager().remove(a);
}
Is there any reason the above assertNull check always fails? I cannot delete the object from my system no matter what I do - no error returned, and no issue with the delete reported. (As an aside, running a query directly in HQL does result in an update of the database...I just can't get it to work using the delete method supplied using JPA...)
Any assistance appreciated
You should take a look into these Hibernate classes/methods:
org/hibernate/engine/spi/ActionQueue.java executeActions(), unScheduleDeletion()
org/hibernate/event/internal/DefaultPersistEventListener.java onPersist()
I had the same problem - not being able to remove an entity. In my case, entityManager had two entities in its 'context': a parent with a list of children entities (cascade = CascadeType.ALL) and a child (from the list) to remove. So when I was trying to remove a child, parent still had a link to it, which was causing Hibernate to 'unScheduleDeletion' upon flushing.
So here is the solution:
Add orphanRemoval = true to the collection of children
Create method deleteChild(Child child) {child.setParent(null); children.remove(child);}
Use this method to delete children
Looks like another solution is to remove cascading, so that merging of parent entity wouldn't cause saving all its children. Not quite sure here (haven't checked).
Also, as far as I remember, JPA spec describes this situation.

unable to add objects to saved collection in GAE using JDO

I have a ClassA containing an ArrayList of another ClassB
I can save a new instance of ClassA with ClassB instances also saved using JDO.
However,
When I retrieve the instance of Class A,
I try to do like the below:
ClassA instance = PMF.get().getPersistenceManager().GetObjectByID( someid );
instance.GetClassBArrayList().add( new ClassB(...) );
I get an Exception like the below:
Uncaught exception from servlet com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found..
So I was wondering, Is it possible to add a new item to the previously saved collection?
Or was it something I missed out.
Best Regards
"no matching index found"
Perhaps you need to add some index in GAE/J's datastore ?
Nothing to do with JDO

Categories

Resources