Inheritance JPA and Hibernate Issue - java

I've a weird problem loading some objects. I'm using JPA 1, hibernate-core version 3.3.0.SP1 and hibernate-entitymanager version 3.4.0.GA
Let's say I've these JPA entities:
#Entity
#Table(name = "SLC_ELE")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(discriminatorType = DiscriminatorType.INTEGER, name = ElementoPrograma.C_ID_CTG_ELE)
public class Element {
...
}
#Entity
#Table(name = "SLC_ELE_ONE")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorValue(Categories.ID_CTG_ONE)
public class ElementTypeOne extends Element {
...
}
#Entity
#Table(name = "SLC_ELE_TWO")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorValue(Categories.ID_CTG_TWO)
public class ElementTypeTwo extends Element {
...
}
#Entity
#Table(name = ThreeElementExample.TABLENAME)
#AssociationOverrides({
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_ONE,
joinColumns =
#JoinColumn(name = Element.C_ID_ELE)),
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_TWO,
joinColumns =
#JoinColumn(name = OneEntity.C_ID_TWO)),
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_THREE,
joinColumns =
#JoinColumn(name = AnotherEntity.C_ID_THREE))})
public class ThreeElementExample extends JpaMany3ManyEntity<Element, OneEntity, AnotherEntity> {
...
}
The thing is, I'd like to obtain always the subclasses (meaning the ElementTypeOne, ElementTypeTwo instead the elements) when I load a collection of these entities. The problem is that the many to many relation always get the Element (the father instead the children)
Let's say I've an entity A containing a colection of Elements:
#Fetch(FetchMode.JOIN)
#OneToMany(cascade = CascadeType.ALL, mappedBy = "idEle")
private Collection<Element> elementCollection;
And if I get the collection, everything works fine (I get the subclasses as expected).
The problem comes when I've another entity B with a collection of the JpaMany3ManyEntity (notice that the same entity element is involved)
#OneToMany(cascade = CascadeType.ALL, mappedBy = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_ONE, fetch = FetchType.LAZY)
private Collection<ThreeElementExample> threeElementExampleCollection;
If I loop the threeElementExampleCollection from class B before I try to obtain the elementCollection from class A, when I load the objects from the elementCollection
I obtain just the superclass (Element) objects instead the children.
I guess that, for any reason, the many to many relationship obtains always the Element objects (father) and saves them in the hibernate cache, but I need to avoid this behaviour.
Any ideas or workarround? Any kind of help would be really appreciated.
Thanks in advance.
EDIT: the many to many class:
#SuppressWarnings("serial")
#MappedSuperclass
#AssociationOverrides({
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_ONE,
joinColumns =
#JoinColumn(name = "changeMeWhenExtends")),
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_TWO,
joinColumns =
#JoinColumn(name = "changeMeWhenExtends")),
#AssociationOverride(name = JpaMany3ManyEntity.ASOCIATION_OVERRIDE_THREE,
joinColumns =
#JoinColumn(name = "changeMeWhenExtends"))})
public abstract class JpaMany3ManyEntity<A extends JpaBaseEntity, B extends JpaBaseEntity, C extends JpaBaseEntity> extends JpaBaseEntity {
public static final String ID_ATTNAME = "id";
public static final String ASOCIATION_OVERRIDE_ONE = JpaMany3ManyEntity.ID_ATTNAME + "." + JpaMany3ManyId.ID_ONE_ATTNAME;
public static final String ASOCIATION_OVERRIDE_TWO = JpaMany3ManyEntity.ID_ATTNAME + "." + JpaMany3ManyId.ID_TWO_ATTNAME;
public static final String ASOCIATION_OVERRIDE_THREE = JpaMany3ManyEntity.ID_ATTNAME + "." + JpaMany3ManyId.ID_THREE_ATTNAME;
...
}

Here's a workarround that works to me: Deproxy the entities.
Even having a parent proxy of the entity (jpa.inheritance.issue.Element_$$_javassist_1) if you deproxy it, you'll obtain the real entities (children).
Let's say you want to loop your (children) elements collection from the entity A and do something with them.
Something like:
public void loopDeproxyElements(List<Element> yourElementsCollection){
for(Element p : yourElementsCollection){
if(p instanceof HibernateProxy){
Element child = (Element) ((HibernateProxy) p).getHibernateLazyInitializer()
.getImplementation();
if (child instanceof ElementTypeOne){
//You can cast your object or do whatever you want, knowing for sure that's a child element)
ElementTypeOne myRealElement = (ElementTypeOne) child;
...
} else {
//It should be ElementTypeTwo (if u never create parent entities)
...
}
}
}
)
It will always get the children elements as I was expecting.

Try experiment with hibernate.default_batch_fetch_size property. By default it's set to 1. This will load only first entity from your collection. Increasing it to ~size of the collection might help.

Related

Migration Hibernate 6

I try to migrate a SpringBoot application to SpringBoot 3. Sprinboot 3 use Hibernate 6.
My application refuse to start because of the following error
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Map.get(Object)" because the return value of "java.util.Map.get(Object)" is null
at org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator.addJoins(AuditMetadataGenerator.java:206)
at org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator.generateSecondPass(AuditMetadataGenerator.java:409)
at org.hibernate.envers.configuration.internal.EntitiesConfigurator.configure(EntitiesConfigurator.java:86)
at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:129)
at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.produceAdditionalMappings(AdditionalJaxbMappingProducerImpl.java:92)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:329)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
... 110 common frames omitted
After digging in the Envers code it appear that the problem is located in the org.hibernate.envers.configuration.internal.metadata.AuditMetadaGenerator class.
At line 337, there is a condition that let a audited class be referenced during the first pass of envers .
if ( entity.isJoinAware() ) {
final JoinAwarePersistentEntity joinAwareEntity = (JoinAwarePersistentEntity) entity;
createJoins( persistentClass, joinAwareEntity, auditingData );
addJoins( persistentClass, propertyMapper, auditingData, persistentClass.getEntityName(), mappingData, true );
}
private void createJoins(PersistentClass persistentClass, JoinAwarePersistentEntity entity, ClassAuditingData auditingData) {
final Iterator<org.hibernate.mapping.Join> joins = persistentClass.getJoinIterator();
final Map<org.hibernate.mapping.Join, Join> joinElements = new HashMap<>();
entityJoins.put( persistentClass.getEntityName(), joinElements );
....
This is this list that is called during the second pass line 206.
while ( joins.hasNext() ) {
final org.hibernate.mapping.Join join = joins.next();
final Join entityJoin = entityJoins.get( entityName ).get( join );
Here entityJoins.get(entityName) return null for one of my entity.
This entity is correctly annotated with #Audited and extend from another Entity like this:
#Entity
#Table(name = "a")
#Audited
#DiscriminatorValue("DISCRIMINATOR")
public class A extends B {
//...
}
#Entity
#Table(name = "b")
#Inheritance(strategy = InheritanceType.JOINED)
#Audited
public abstract class B {
//...
}
In my comprehension, specifying the Inheritance with a value of InheritanceType.JOINED make envers create a JoinedSubclassPersistentEntity that itself inherit from PersistentEntity.
This PersistentEntity has a method :
public boolean isJoinAware() {
return false;
}
that is overriden by it's children like RootPersistentEntity by :
#Override
public boolean isJoinAware() {
return true;
}
This override is not made by JoinedSubclassPersistentEntity which is the class generated when using Joined inheritence strategy.
This cause my entity to not be add to the first pass but still processed by the second pass.
So the question is ? Is it a bug in Envers ? Can i used Joined inheritence strategy with a #Audited class ?
It was working well in hibernate 5.6.
[Edit]:
I managed to reproduce the error with a simple test class :
#Entity
#Audited
#DiscriminatorValue("OPTION")
public class Child extends Parent{
private String propA;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "recursive_children_child", joinColumns = {#JoinColumn(name = "child_id", nullable = false, updatable = false)}, inverseJoinColumns = {#JoinColumn(name = "recursive_id", nullable = false, updatable = false)})
#NotAudited
#OrderBy("propA DESC")
private List<Child> children = new ArrayList<>();
#ManyToOne(fetch = FetchType.LAZY)
#JoinTable(name = "recursive_children_child", joinColumns = {#JoinColumn(name = "recursive_id")}, inverseJoinColumns = {#JoinColumn(name = "child_id")})
#NotAudited
private Child recursiveChild;
public Child(String propA) {
this.propA = propA;
}
public Child() {
}
public String getPropA() {
return propA;
}
public void setPropA(String propA) {
this.propA = propA;
}
}
The problem seems to be with the recursive relationship in the Child class. Ember try to audit the relationship despite the presence of #Audited annotation.
Link to a project that reproduce the bug => https://github.com/scandinave/envers6-migration-bug
I finally found the problem by reading the Jakarta Persistence Spec.
The JoinTable annotation is used in the mapping of entity associations. A JoinTable annotation is
specified on the owning side of the association
In my project there is a #JoinTable annotation on both side of the association. This was working before Hibernate 6, but not now. I just had to remove the #JoinTable not needed to solve the error.

Spring JPA can't persist collection item with related existing entity - detached entity passed to persist

I got an issue when trying to persist an item of a collection and one of its properties is an already persistent entity in a database.
Trying to clarify by this simplified example:
Class A has a List of class B (One to Many, mappedBy, CascadeType.PERSIST, CascadeType.MERGE)
Class B is related back to A (Many to One, JoinColumn)
Class B inherits from BParent (Single Table)
BParent is related to class C (Many to One, CascadeType.MERGE, CascadeType.PERSIST)
When i run ARepository.save(entity) passing a complete object to it (with a List of B including one B entity with a new C associated) it persists all entities normally.
When i run ARepository.save(entity) passing an object related with existing (with List of B including a B entity realted with a EXISTING C associated, i.e. id only) it triggers the dettached entity passed to persist error.
org.hibernate.PersistentObjectException: detached entity passed to persist: C
What im trying to do is to save a new related object (when it has no id) or associate to an existing object (when it has an id).
My respositories are all Spring Data JpaRepository interfaces. My code goes like this (getters and setters ommited):
#Entity
public class A {
#OneToMany(mappedBy = "bEntity", cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private List<B> bList = new ArrayList<>();
}
#Entity
#DiscriminatorValue("B")
public class B extends BParent {
#ManyToOne
#JoinColumn(name = "CVLE_CVL_UUID")
private A bEntity;
}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "CVLE_TIPO")
#Table( name = "TAB_CONTA_VINCULADA_LANC_EMPREGADO")
public abstract class BParent {
#Id
private UUID id;
#ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
#JoinColumn(name = "CVLE_EMP_UUID")
private C cEntity;
}
#Entity
#Table( name = "TAB_EMPREGADO")
public class C {
#Id
#Column(name = "EMP_UUID")
private UUID id;
}
I hope i could explain it right (english is not my first language). I would appreciate if someone could give me a hand on this, thank you.

JPA Inheritance issue

Working with JPA 1 (hibernate-core version 3.3.0.SP1 and hibernate-entitymanager version 3.4.0.GA) :
I've some entities similar to those defined below, where ChildOne and ChildTwo extends from the Father entity.
#Entity
#Table(name = "TABLE_FATHER")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(discriminatorType = DiscriminatorType.INTEGER, name = Father.C_ID_CTG)
public class Father {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "sq")
#Column(name = "ID_PK", nullable = false)
#BusinessId
private Long id;
...
}
#Entity
#Table(name = "TABLE_CHILD_ONE")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorValue(Categories.ID_CTG_ONE)
public class ChildOne extends Father {
...
}
#Entity
#Table(name = "TABLE_CHILD_TWO")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorValue(Categories.ID_CTG_TWO)
public class ChildTwo extends Element {
...
}
Let's say I've one entity having a Father element, and another having a collection of father elements. In both cases, should go the children entities.
#Entity
#Table(name = "TABLE_ONE")
public class OneTable {
#JoinColumn(name = "ID_PK", referencedColumnName = "ID_PK", nullable = false)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Father element;
...
}
#Entity
#Table(name = "TABLE_ANOTHER")
public class Another {
#Fetch(FetchMode.JOIN)
#OneToMany(cascade = CascadeType.ALL, mappedBy = "id", fetch = FetchType.LAZY)
private Collection<Father> elementCollection;
...
}
I'm expecting to obtain always the children elements but when I get the element getElement() returns the father element
and, on the other hand, when I get the collection getElementCollection() the children elements are coming.
Apparently, the #JoinColumn is the cause of this behaviour, doing the join with the father table and forgetting the children elements.
The collection is working as expected.
How could I get the children element with a getElement() call? Any ideas or workarround?
Thanks in advance.
The problem is not caused by #JoinColumn.
The reason is Lazy Loading.
I manage to pinpoint your problem in simpler example.
Forgive me for changing convention from Father to Parent.
In the example below, uninitialized Element is type of jpa.inheritance.issue.Parent_$$_javassist_1. It is a Hibernate Proxy - dynamically created subclass of Parent.
You can "unproxy" it by invoking Hibernate proprietary API getHibernateLazyInitializer().getImplementation().
Collection of elementCollection is also Lazy Initialized. The type of the collection is org.hibernate.collection.PersistentBag which is being initilized with correct data at the time of first access.
Collection is initialized all at once.
Please see the test which successfully passed green with your exact version of Hibernate (3.3.0.SP1/3.4.0.GA).
#Test
public void test() {
Child c = new Child();
em.persist(c);
Another a = new Another();
a.setElement(c);
Collection<Parent> col = new ArrayList<Parent>();
col.add(c);
a.setElementCollection(col);
em.persist(a);
c.setAnother(a);
long idx = a.getId();
tx.commit();
// I'm cleaning the cache to be sure that call to a.getElement() will return proxy.
em.clear();
tx = em.getTransaction();
tx.begin();
a = em.find(Another.class, idx);
Assert.assertNotNull(a);
Parent p = a.getElement();
// At this point p is a type of jpa.inheritance.issue.Parent_$$_javassist_1
Assert.assertTrue(p instanceof Parent);
Assert.assertFalse(p instanceof Child);
// At this point a.elements is a not initialized (empty) collection of type org.hibernate.collection.PersistentBag
// When we access this collection for the first time, records are read from the database
Assert.assertEquals(1, a.getElementCollection().size());
if (p instanceof HibernateProxy) {
p =
(Parent) ((HibernateProxy) p).getHibernateLazyInitializer()
.getImplementation();
}
// At this point p is a type of jpa.inheritance.issue.Child
Assert.assertTrue(p instanceof Child);
}
#Entity
public class Another {
#JoinColumn(name = "element_id", referencedColumnName = "id", nullable = false)
#ManyToOne(fetch=FetchType.LAZY)
private Parent element;
public Parent getElement() {
return element;
}
public void setElement(Parent element) {
this.element = element;
}
#OneToMany(cascade = CascadeType.ALL, mappedBy = "another", fetch = FetchType.LAZY)
public Collection<Parent> elements;
public Collection<Parent> getElementCollection() {
return elements;
}
public void setElementCollection(Collection<Parent> elementCollection) {
this.elements = elementCollection;
}
// #Id ...
}
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Parent {
#ManyToOne
private Another another;
public Another getAnother() {
return another;
}
public void setAnother(Another another) {
this.another = another;
}
// #Id ...
}
#Entity
public class Child extends Parent {
}
You don't need #DiscriminatorColumn nor #DiscriminatorValue because those annotations are needed with InheritanceType.SINGLE_TABLE as an only resort to determine the type.
With InheritanceType.JOINED Hibernate is able to determine polymorphic type by checking if there is a record in both (Parent and Child) tables with the same Id.
You can turn on hibernate logging to see how the query to determine the type looks like. It works like this:
select
another0_.id as id0_1_,
another0_.element_id as element2_0_1_,
parent1_.id as id1_0_,
parent1_1_.name as name2_0_,
case
when parent1_1_.id is not null then 1
when parent1_.id is not null then 0
else -1
end as clazz_0_
from
Another another0_
inner join
Parent parent1_
on another0_.element_id=parent1_.id
left outer join
Child parent1_1_
on parent1_.id=parent1_1_.id
where
another0_.id=?

Hibernate not updating ManyToMany associations during session

I am working on a project using Hibernate 4.3.4 to access a Postgres DB. We have two entities which are linked via a ManyToMany Association.
The code and the associations currently work, in that adding an EntityB to EntityA's collection will automatically add the EntityA to the EntityB's collection once the Session is committed. However, the issue I'm having is that when I try to work on the EntityB's EntityAs, which should include the EntityA I just created, EntityA is not in that collection (It is empty). Example code is here:
#Entity
#Table(name = "entity_a")
public class EntityA {
private Set<EntityB> entityBs = new HashSet<EntityB>(0);
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "entitya_entityb",
joinColumns = { #JoinColumn(name = "entitya_id") },
inverseJoinColumns = { #JoinColumn(name = "entityb_id") })
public Set<EntityB> getEntityBs()
{
return entityBs;
}
public void setEntityBs(Set<EntityB> entityBs)
{
this.entityBs = entityBs;
}
}
#Entity
#Table(name = "entity_b")
public class EntityB {
private Set<EntityA> entityAs = new HashSet<EntityA>(0);
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "entitya_entityb",
joinColumns = { #JoinColumn(name = "entityb_id") },
inverseJoinColumns = { #JoinColumn(name = "entitya_id") })
public Set<EntityA> getEntityAs()
{
return entityAs;
}
public void setEntityAs(Set<EntityA> entityAs)
{
this.entityAs = entityAs;
}
}
/**
* HTTP REST Resource to create Entities and persist them. We do some basic logic when we create them to show the problem.
*/
#Path("/battleRhythm")
#Singleton
public class HttpResource
{
#POST
#Consumes("application/json")
public void createEntityA() {
Session hibernateSession = SessionFactory.getCurrentSession(); // SessionFactory specifics not included
hibernateSession.getTransaction().begin();
// Add an EntityB to the new EntityA
EntityA entityA0 = new EntityA();
EntityB entityB0 = new EntityB0();
entityA.getEntityBs().add(entityB0);
// Persist the new EntityA
EntityADao.getInstance().save(entityA0);
// Try to get this EntityA from EntityB
Set<EntityA> associatedEntityAs = entityB0.getEntityAs(); // Doesn't contain any EntityAs!
hibernateSession.getTransaction().commit();
}
}
Here's the question:
Can I make Hibernate automatically add the EntityA0 to EntityB0's collection when I save EntityA0, without committing the transaction? Is this possible? How?
Caveat : The example above does not fully reflect this, but we perform similar operations on both Entities, so having an "owner" in the traditional Hibernate sense (using the mappedBy = "" Attribute configuration) is not an ideal option. I don't want to try to convince everyone to only ever use EntityB.getEntityAs().add(EntityB0) in CreateEntityA(). It's too confusing.
You don't have the choice. There MUST be an owner side, and there MUST be an inverse side. And it's YOUR responsibility to maintain both sides of the association: don't expect to have B inside A's collection of Bs when you only add A to B (and vice-versa)
Now, nothing forbids you to have a methods addB(B b) inside A that adds b to A's collection of Bs, and which adds this to B's collection of As. And you can of course also have a method addA(A a) in B that does the same thing.

Column index out of range when creating alias with criteria

Ok so I get this weird issue that I can't fix.
I have 3 entities ( i will write things that only matters imo)
#Data
#Entity // all # are in javax
#Table(name = "a", schema = "pl")
#SequenceGenerator(...)
public class A extends BaseEntity {
#OneToMany(mappedBy = "pk.a")
private Set<ABRel> Bs = new HashSet<ABRel>();
}
#Getter
#Setter
#Entity
#Table(name = "a_b_rel", schema = "pl")
public class ABRel implements IEntity {
#EmbeddedId
private OfferOrderProjectRelId pk;
public OfferOrderProjectRel(B b, A a) {
if (a == null || b == null) {
throw new IllegalArgumentException("B orA equals null");
}
B.addA(this); // this methods just adds ABRel to sets in A and B
A.addB(this);
pk = new ABRelId(b, a);
}
}
#Getter
#Setter
#Embeddable
#EqualsAndHashCode
public class OfferOrderProjectRelId implements Serializable {
#ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
#JoinColumn(name = "b_id")
private B b;
#ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
#JoinColumn(name = "a_id")
private A a;
public ABRelId(B b, A a) {
setB(b);
setA(a);
}
}
#Data
#Entity (it has javax import)
#Table(name = "b", schema = "pl")
#SequenceGenerator(...)
public class B extends BaseEntity {
#OneToMany(mappedBy = "pk.b")
private Set<ABRel> As = new HashSet<ABRel>();
#NotBlank
#Length(max = 10000)
#Column(name = "type", length = 10000, nullable = false)
private String type;
}
ABRel and ABRelId have private contructor (ABRel() and ABRelId()) but not sure if it matters. Entities are working just fine, so I don't think somethink is wrong with them but meaby I am wrong.
So I'm tryin to add criteria by B.type for my filters. Criteria are made "in" (not sure how to say it :) ) A.class. So here's criteria that I'm tryin to add in my dao ( I can add this to criteria not detached one if someone ask):
DetachedCriteria idCriteria = DetachedCriteria.forClass(A.class, "a");
idCriteria.createAlias("Bs", "btype", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("Bs.pk.B.type", "someType"));
Criteria criteria = getSession().createCriteria(A.class, "a");
criteria.add(Subqueries.propertyIn("id", idCriteria));
What I am tryin to achieve is to get all ABRels that have some specified B.type, then I will have to count it somehow, but this is not my issue atm. I have to use criteria, can't use any HQL. I also read that hibernate has some kind of bug with creating alias beetwen entity and its embedded so I can't make it too (probably thats why I am having to much trouble with it). So any ideas? I'm running out of option so any help would be great!
I almost forget, I'm getting this error
org.hibernate.HibernateException: Unknown entity: null at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getPropertyMapping(CriteriaQueryTranslator.java:638)
at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getType(CriteriaQueryTranslator.java:587)
at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getTypeUsingProjection(CriteriaQueryTranslator.java:569)
at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getTypedValue(CriteriaQueryTranslator.java:627)
at
org.hibernate.criterion.SimpleExpression.getTypedValues(SimpleExpression.java:100)
at
org.hibernate.loader.criteria.CriteriaQueryTranslator.getQueryParameters(CriteriaQueryTranslator.java:335)
at
org.hibernate.criterion.SubqueryExpression.createAndSetInnerQuery(SubqueryExpression.java:151)
at
org.hibernate.criterion.SubqueryExpression.toSqlString(SubqueryExpression.java:68)
UPDATE:
I have added sth like this
criteria.createAlias("As", "oorel", JoinType.LEFT_OUTER_JOIN);
criteria.createAlias("oorel.pk.b", "order", JoinType.LEFT_OUTER_JOIN, Restrictions.eq("type", "order"));
And now I'm getting new error(it's in my native language so i will try to translate it) its postgres and hibernate exception :
Column index out of range: 1, number of columns: 0
Sorry for my bad english and thank you in advance.
This is unfortunetly a hibernate bug which havent been fixed yet. This error appears because hibernate is not able to create alias via entity that contains composite key.

Categories