I have 3 entities:
#Entity
#Table(appliesTo = "A", indexes = {#Index(name = "a_uuid_idx", columnNames = {"uuid"})})
public class A {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EntityID")
#Access(AccessType.PROPERTY)
private Integer id;
}
#Entity
#DiscriminatorValue("local.stored")
public class B extends A {
private String name;
}
And data from B successfully persists in table A.
#Entity
#DiscriminatorValue("second.stored")
public class C extends B {
private String lastname;
}
I expected, data from C to be persisted to table A (so, 3 etitties in one table). But it does not, despite the fact that DiscriminatorValue is used.
I tried also to aplly to class B annotation #Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) in the hope that separate table for C will be created (so, 2 tables: 1 - for A/B and 2 - for C). But without success.
Related
I have an abstract base class:
#Inheritance(strategy = InheritanceType.JOINED)
#Getter
#Setter
#Entity
#ToString
public abstract class BillingDetails {
#javax.persistence.Id
#GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "pk_for_inheritance")
Long Id;
#NotNull
private String owner;
}
and one subclass extending base class
#Entity
#Getter
#Setter
#ToString(callSuper = true)
public class CreditCard extends BillingDetails{
#Basic(optional = false)
private String cardNumber;
#Basic(optional = false)
private LocalDate expDate;
#Basic(optional = false)
private String cardKey;
}
when I query against base Entity BillingDetails and print results like so:
List<BillingDetails> details=billingDetailsRepository.findAll();
details.forEach(System.out::println);
I get the following output:
CreditCard(super=BillingDetails(Id=1, owner=Mehmet Dogan), cardNumber=6145 1233 4577 2360, expDate=2022-05-03, cardKey=673)
My question is:
Although I understand in joined strategy hibernates joins related base and sub tables ,How is it possible that I can print properties of subclass CreditCard when my result list is of type BillingDetails and only Id and Owner properties are declared in my base class ?
What I have missed here was I think polymorphism. When I tried to get Class of results like
List<BillingDetails> details=billingDetailsRepository.findAll();
details.forEach(x-> System.out.println(x.getClass()));
I got the following output :
class com.rumlor.domainmodelmapping.models.inheritancemodels.CreditCard
so somehow I missed somewhere even if results are cast to List Of BillingDetails ,Hibernate polymorphed every sub instance to base entity for me.
additional check :
CreditCard card= (CreditCard) details.get(0);
System.out.println(card);
result :
CreditCard(super=BillingDetails(Id=1, owner=Mehmet Dogan), cardNumber=6145 1233 4577 2360, expDate=2022-05-03, cardKey=673)
I want to write a join query for joining two tables in Spring Data, using Hibernate.
sql: select * from a join b on a.B_Id=b.id;
My classes are as below:
In class A, I don't have reference of B, I have only B_id. Since its a large project I can't change the class definitions. But need to migrate the join queries to Hibernate.
Any way I can do it?
#Entity
#Table(name = "a")
public class A {
#Id
private Integer id;
// ...
private Integer B_Id;
}
#Entity
#Table(name = "b")
public class B {
#Id
private Integer id;
// ...
}
Many to one mapping -> many A can have the same B.
For example, table A has primary key id, referenced id is bid; table B also has primary key id equal to bid, filedB and more.
My question is that by using Java JPA how to find by B.fieldB?
ADAO extends CrudRepository{
findBy(____);//find by referenced bid related table's fieldB.
}
Entity class example:
#Entity #Table(name="A") public class A implements Serializable{ id; bid; };
#Entity #Table(name="B") public class B implements Serializable{ id; fieldB; }
According to #manish suggestion, that's worked on my side.
First off, using annotation to define the relation ship between A and B;
#Entity #Table(name="A") public class A implements Serializable{ id; bid;
#JoinColumn(name = "bid") #ManyToOne B b;
};
#Entity #Table(name="B") public class B implements Serializable{ id; fieldB; }
Then findByBFieldB(string fieldB) in my A-Repository;
Another way: using annotated query as following:
#Query(value = "SELECT a.* FROM A a LEFT JOIN B b ON a.bid=b.id WHERE b.field LIKE :someString", nativeQuery = true);
I wish I could do as well.
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.
I'm trying to select entries for Entity A where all of the children in its collection of CReference entities meet a condition. The query I currently have only requires the conditions to be met on at least one of the members.
Current Query
This query currently selects all objects of type A where at least one of the items in its c_references class
SELECT a FROM A a INNER JOIN FETCH a.c_references c_refs INNER JOIN FETCH c_refs.c_reference c_ref WHERE (c_ref.flag_one=TRUE AND c_ref.flag_two=TRUE)
Classes
Class A
#Entity
public class A{
#Id
private UUID a_uuid;
#OneToMany(fetch = FetchType.EAGER)
#JoinColumn(name = "owning_a_uuid")
private List<CReference> c_references;
}
Class CReference
#Entity
// This class keeps references to all of the A objects that have referenced a C object
public class CReference{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long c_reference_id;
#OneToOne
private A a_referencing_c;
#OneToOne
private C c_reference;
}
Class C
#Entity
#Cacheable
public class C{
#Id
private UUID c_uuid;
private Boolean flag_one = false;
private Boolean flag_two = false;
}
Try this:
SELECT a FROM A a
WHERE NOT EXISTS(
SELECT c_refs
FROM CReference c_refs
INNER JOIN c.c_reference c_ref
WHERE
c_refs.a_referencing_c = a
AND (c_ref.flag_one = FALSE OR c_ref.flag_two = FALSE)
)