How to load JPA-JoinTable entities, from an entity selected with mybatis? - jpa

I have 3 tables for this case. Table A, Table B, Table ab that has relationship between A and B.
Class A has a list of B annotated with JoinTable and OneToMany, and Table ab is being used for this.
public class A {
// ...
#OneToMany( ... )
#JoinTable( ... )
List<B> bList;
}
Class A is loaded with MyBatis, cause some nested query is needed for this api.
And being loaded by MyBatis, bList is remaining empty.
Is there any way to load bList with jpa, when class A is loaded by non-jpa method ?

Related

JPA annotation for mapped entity with values based on the root entity?

I'm trying to annotate my JPA-Entity. In the entity I want to map another Entity which should be loaded by values of the root entity.
Example:
Entity A has the fields key1 & key2.
I want to map Entity B which should be loaded by the filter b.key1 = a.key1 & b2.key2 = a.key2
Can anyone help?
I got the solution. I just used #ManyToOne and #JoinColumns:
#ManyToOne
#JoinColumns(
{
#JoinColumn(name="key1", referencedColumnName="refKey1"),
#JoinColumn(name="key2", referencedColumnName="refKey2")
}
)
private EntityB entityB;

Fluent NHibernate Create entity mapping for overlapping entities

For eg. I have two tables in my database
NonResidentStudents - columns studentID, studentname, ModeOfTransport
ResidentStudents - columns studentID, studentname, DateOfJoiningHostel
studentID and studentName are common columns and the last column is uncommon between the two
For some reason, I cant change these tables or define a common master table and make uncommon columns in sub tables. So the table stucture is rigid.
Now when trying to create an entity and mapping for the above schema using FLUENT NHIBERNATE (only) I would like to know if I can define some sort of a common entity and common mapping for the common columns and create child entities inheriting from the common entities. In the child entity and mapping class I will have representations for the uncommon columns. Could anyone please share code of how to do it.
I did this before.
Common Class
public class BaseMapping : ClassMap<EntityBase>{
public BaseMapping ()
{
UseUnionSubclassForInheritanceMapping ();
// All the rest of the mapping attributes
}
}
For your individual classes that will inherit from the base you do this:
public class DepartmentMapping : SubclassMap<Department>
{
public DepartmentMapping ()
{
Abstract ();
// Map all the unique attributes
}
}
The code above will create one class based on Department and EntityBase. It will not create a table called EntityBase.

JPA Cascade remove orphans

I have a question. I use JPA with eclipselink and I have relationship:
Table A ---< Table AB >---- Table B
class A {
#OneToMany(mappedBy = "a")
private List<AB> abList
}
class AB {
#ManyToOne(fetch = FetchType.LAZY)
private A a;
#ManyToOne(fetch = FetchType.LAZY)
private B b;
}
class B {
#OneToMany(mappedBy = "b")
private List<AB> abList;
}
It is ManyToMany relationship between A and B with join table AB.
Now I want to remove a record from table A and to cascade remove records from table AB(join table) and from B table as well.
But from B only those which arent't connected to any other record from table A (many-to-many relationship between A and B).
How should I set CascadeType or orphanremoval to do it properly?
If you want to remove AB and B when A is deleted then just set cascade remove, (and orphanRemoval=true if you want removed instances to be removed).
If the relationship from A to B is truly ManyToMany, i.e. B can have multiple references, then you cannot cascade the remove to B, (but can still cascade to AB, ensure you maintain bi-directional relationships in your model).
There is no way to delete B if there happens to be no relationship to it from anywhere. This would be something like garbage collection, which does not exist in relational databases. You need to handle this from your application. If B is something you want to delete with A, then consider not having it shared, but have each A have its own private B instance.
I suppose you are working with Hibernate
you should make an orphanRoval=true,
after that try this:
supposing we needto remove a (which class is A),
we make :
for (AB ab : a.getAbList()) {
B b = ab.get();
if (b.getAbList().size()==1) {
em.remove(b);
}
em.remove(ab);
}
em.remove(a);
Hope this help

Entity Framework atypical 1-[0..1] -- model-only Association -- EF LINQ select possibilities

Suppose the following tables
ParentEntities
ParentID
ChildEntities
ChildID
ParentID
These tables do not have a FK defined in the schema.
In EF designer, after generating from DB, I add an association:
- Parent Multiplicity: 1
- Child Multiplicity: 0 or 1
When I build, I get the error: "Error 3027: No mapping specified for the following EntitySet/AssociationSet - ParentChild"
But if I try to configure table mapping for the association like this..
Maps to ChildEntities
Parent
ParentID <-> ParentID (parent entity prop <-> child table column)
Child
ChildID <-> ChildID (child entity prop <-> child table column)
.. I get this: Error 3007: Problem in mapping fragments starting at lines xxx, xxx: Column(s) [ParentID] are being mapped in both fragments to different conceptual side properties.
Why this is an error doesn't make sense. Limitation of the current implementation?
[EDIT 1]
I'm able to make this work by creating a 1-N association. That's not ideal, but it works just the same, just have to add a read-only child property in a partial:
public partial class Parent
{
public Child Child { get { return Childs.Any() ? null : Childs.First(); } }
}
This seems like the best solution for me. I had to add a FK to the database to get EF to generate the association and navigation property, but once it was added I was able to remove the FK, and further updates to the model from the DB did not remove the association or Navigation properties.
[EDIT 2]
As I was investigating how to work around not caring about the association being modeled in EF, I ran into another issue. Instead of the read-only Child property I made it normal ..
public partial class Parent
{
public Child Child { get; set; }
}
.. but now I need a way to materialize that from the query:
var query = from parents in context.Parents
// pointless join given select
join child in context.Childs
on parents.ParentID equals child.ParentID
select parents;
I can select an anonymous type ..
// step 1
var query = from parents in context.Parents
join child in context.Childs
on parents.ParentID equals child.ParentID
select new { Parent = parents, Child = child };
.. but then I've got to consume more cycles getting that into my entity:
// step 2
var results = query.Select(x => {
var parent = x.Parent;
parent.Child = x.Child;
return parent; });
Is there a better/streamlined way to do this from the query select so the EF materializer can do it from the get-go? If not, then I'll resort to Edit 1 methodology ..
Ef Code first requires 1->0..1 relationships for the Child to have the same primary key.
Maybe this a similar restriction In the modeler in this circumstance.
ParentId (Key) required in Both tables.
I have never tried adding such relationships in designer afterwords in DB first.
EDIT: to match your EDIT2:
I would stay on the direction . Use Navigation properties to get from Join back to original class A and B.
query = context.Set<JoinTable>.Where(Jt=>Jt.NavA.Id == ClassAId
&& Jt.navB.Id == ClassBId)
use a select if your need entries returned from either ClassA or ClassB.

Hibernate Envers : track revisions in the owning side of a OneToMany relation

I have two audited entities, A and B. Entity A holds a collection of entity B (annotated as One-to-many relationship). When inserting a new instance of A into the database, all rows of A and B are at the same revision (let's say revision 1). Then, there is an update on A which only affect the instances of entity B (cascade type is merge). So after the update, the entity A is still at revision 1, whereas the entities of B are at revision 2 (new MOD entry in the audit table).
The problem is when I retrieve all the revisions of A, I would expect to get 2 revisions in return : one for the creation, one for the modification of the owning collection of B.
I can get this behaviour in case of ManyToMany but I can't get it work the same way with a OneToMany relation.
(I'm using Hibernate 3.6.10-Final)
I solved my problem by adding a hidden lastUpdated date field on my equivalent of your A entity.
#Entity
public class A {
private Date lastModified;
#OneToMany(mappedBy = "a", cascade = CascadeType.ALL )
private List<B> blist;
public void touch(){
lastModified=new Date();
}
}
In the related entities (like you B field), I added the following :
public class B {
#ManyToOne
private A a;
#PreUpdate
public void ensureParentUpdated(){
if(a!=null){
a.touch();
}
}
}
This ensures that a revision is added to A whenever a revision is added to B.