Java EE, creating entity object with one to one association - java

I have two entitys, A and B. A has a one to one relationship of B.
class A {
String aValue;
B b;
}
class B {
String bValue;
}
The class B stuff are already pre populated. Now, a user on a website selects what B he wants to submit. On the server we get an Id of what B that was.
The Question:
How do I create a new A, without actually do a DB query asking for the B that has this id. I mean, the A table in database only has a id reference. One should be able to set that Id without fetching the B.

If you are using JPA and Assuming the following:
#Entity
#Table(name="A")
class A {
#Id
#Column(name="id")
private int id;
String aValue;
#OneToOne
B b;
// Getters, setters and other stuff
}
#Entity
#Table(name="B")
class B {
#Id
#Column(name="id")
private int id;
Integer Id;
String bValue;
// Getters, setters and other stuff
}
If you now the id of entity B. You can simply make persist as follows:
B b = new B();
b.setId(1000); //Assuming that you know the id.
//There is no necessary fill all the object. Just the PK is needed.
A a = new A();
a.setId(100);
a.setAValue("nothing");
a.setB(b);
em.persist(a);
I have tested this with Hibernate as Persistence Provider. If you are using other ORM please specify it.

You should take a look at JPA 2.0.
With JPA you can define a relationship between 2 entites to automatically retrieve the related entities.

Related

JPA foreign key - insert new record if necessary?

Is it possible to create some combination of annotations, that provide following:
Have 2 tables (one-2-many relationship)
Is it possible on JPA level without programming, just create object of "one" class and if there is id set that just make it reference in "many" table and in case that id is not set, create new record in "one" table and make reference to that id in "many" table
No. You will need to create all the objects by your self.
What you can do is to use cascade to do a automatic persist if you want to.
It would be something like:
a.setB(b);
b.getAList().add(a);
entityManager.persist(a);
And in your classes you would map like:
public class A {
// other methods and ID
#ManyToOne
#JoinColumn(name = "b_id")
private B b;
}
public class B {
// other methods and ID
#OneToMany(mappedBy = "b", cascade = CascadeType.PERSIST)
private List<A> aList;
}

Is there any functionality in JPA which would mirror a non existent #PreCascadePersist functionality

I am trying to Persist an object A which has fields b and c which are marked as Cascade All. What I want to do is to be able to run a pre-defined method when b and c are being persisted because A is getting persisted.
A #PrePersist won't work, because I want this method to only kick in - in case b and c are getting persisted through a Cascade operation on A. If b and c are getting persisted independently, I do not wish to run this line of code.
example:
#Entity
public class A{
#Id;
Long id;
#OneToOne(mappedBy="a",cascade=CascadeType.ALL)
B b;
}
#Entity
public class B{
#Id
Long id;
String field;
boolean isCascaded;
}
So here what i want is to mark each individual object of Class B which was cascaded through A and not independently to have the field
isCascaded
stored as 'true'. I can't use a #PrePersist since that will always be called irrespective of whether B is getting persisted through a cascade operation or independently.

Composite primary key with not primitive attributes

I am new to Java and Hibernate. I've got problem with composite key. I am trying to do something like that:
#Entity
class A {
#Id
int id;
}
#Entity
class B {
#Id
int id;
}
#Entity
class C {
#EmbeddedId
C_PK c_pk;
}
#Embeddable
class C_PK {
A a;
B b;
}
When I perform
...
session.save(c);
...
Then exception is thrown that type of A and B cannot be inserted into database. Is it possible to somehow tell hibernate to don't save the A object but only the A id? Is my approach absolutely wrong and should I just use primitive data types at C_PK class?
You should put a #ManyToOne (or OneToOne) with join columns on the A and B references in C_PK.
#Embeddable
class C_PK {
#ManyToOne
A a;
#ManyToOne
B b;
}

JPA: uni-directional OneToMany question

I have the following classes:
class A{
#OneToOne(cascade=CascadeType.ALL)
private B b;
}
class C{
#ManyToOne
private A a;
}
class B{
#OneToOne
private A a;
#MapKey(name = "name")
#OneToMany(cascade = CascadeType.ALL, ...)
#JoinColumn(...)
private Map<String C> cs;
}
How do I have to specify the mapping on B.cs to join where B.a == C.a?
Is this possible? Or do I have to change the property C.a to C.b? (I would prefer to keep it as it is, as the entity B is just a helper class.)
I also tried to change B to #Embeddable, but Map is not supported for embeddables.
JPA requires that all relationships be by Id (the foreign key references the primary key).
So, you need to either add a #ManyToOne from C to B.
Or, ensure that B's Id is the foreign key to A (add #Id on the #OneToOne from B to A and remove A's other #Id).
If B was a subclass of A instead of having a OneToOne this would also work.
If you are using EclipseLink, you can defined more complex criteria for a relationship. You would need to define the OneToMany's foreign keys using a DescriptorCustomizer and the OneToManyMapping API.
I think you can extends B from A.
If this doesn't work for you, maybe you can add a transient property to refer A's id,
#Transient
Integer getId1() {
return a.getId();
}
and join C using id1 instead of B's primary key.
Edit: This doesn't work.

Hibernate not fetching public member

Consider the following code:
#Entity
#Table(name = "a")
public class A implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
public int id;
#Transient
public B b;
public B getB()
{
return B;
}
}
When I fetch A, I'm manually filling B (another hibernate entity). If I try and access by by using a.b, then it fails, but, if I user a.getB(); then it succeeds.
Why is this?
Class members should ever be private!
If your object is attached to the Hibernate Session, you're working on a proxy. So, if you like to access your class member directly (which is bad!), you have to detach the object first.
Sounds like a lazy fetching issue. The public reference is null when you try to access it directly, but when you do it with "get", Hibernate knows to call out to the database and hydrate that instance for you.
Because b field is transient.
Is there any need for it to be transient? Try removing it.

Categories