JPA cascade persist - many to one - jpa-2.0

I have a many to one relationship and I am trying to persist a child entity.
public class Office
{
public int id;
public int grades;
#OneToMany
public set<Employee> employees;
}
public class Employee{
#GeneratedValue(strategy=GeneratedValue.identity)
public int empid;
#ManyToOne(cascade=cascadeType.ALL)
public Office office;
}
Office Id is already present in the database. But employee is not.
Now if i am adding an employee and his grades must go into the office database.
When i do the following operation,grades are not getting saved
Office office = new Office();
office.setId(23);
office.setGrades(5);
employee.setOffice(office);
em.persist(employee);
How to save grades into the office table in a single operation

First, fix your mapping.
The association is bidirectional, and one of the side (the one side) must be marked as the inverse of the other using the mappedBy attribute:
#OneToMany(mappedBy = "office")
public set<Employee> employees;
The employee is only one of the employees of the office. Do you really want to delete the entire office when you delete a single employee? If not, why do you put a cascade=cascadeType.ALL on the #ManyToOne? Those annotations have consequences. Don't use them without understanding them.
Now to really answer the question. If the office already exists in the database, you should not build a new one. Go fetch it from the database and update it:
Office office = em.find(Office.class, 23);
// office is now attached, and any change you make on the entity will be written to the database
office.setGrade(5);
Now you may also attach the office to the new employee. But since it's a bidirectional relationship, you should also initialize the other side of the association to keep the object graph coherent:
employee.setOffice(office);
office.addEmployee(employee);
em.persist(employee);

Related

Partialiaze objects in JAVA

Let's say I have a list of Person with some attributes. For each object in this list I want to create a new Person object but only based on some of its attributes.
The Person object has the following attributes : age, name, disease.
I want to create a new Person only on its age and name. The disease attribute must be confidential.
How could I do that ?
Thanks in advance !
You very easily could do this by creating a new object entirely which does not hold that information. For example, you could make a class such as this
public class PersonNoDisease {
private int age;
private String name;
...
}
If you want to make sure that PersonNoDisease still has many of the same methods that the original person class did, you should create an interface that they both implement to ensure that they both have the methods which you think they should both have. If you don't have getters in the Person class, you should make those so that it will be easier to initialize this new class.

OData handling of collections and maps in queries/aggregations

The OData standard is pretty straight forward when it comes to doing queries and aggregations on fields, but I am having trouble wrapping my head around querying/aggregating against a field that is a collection or map.
For instance, lets say I have the following random class:
public class Teacher{
public String name;
public String city;
public List<Class> classes;
public Set<TeachingAssistant> TAs;
public Map<Class,List<Student>> studentsPerClass;
public Teacher(...){
//init all variables
}
}
Now, this is just an example. For the purpose of this example, the teacher class is the only way to get at students, Tas, and Classes. So, all of my queries and aggregations will need to be run off a collection of teachers. With that in mind, I have some questions:
How do I do aggregations on the list of classes? Like if I wanted to know the number of classes offered by a teacher, how would I do that in an OData query?
For instance, I would like to do something like:
.../Teachers?$apply=aggregate(classes with CountDistinct as totalClasses)
or maybe:
.../Teachers?$apply=aggregate(classes(*) with CountDistinct as totalClasses)
Would either of these be the correct way?
If I want to query a specific item in a list or set, how do I access it? A Set in java is not ordered and does not have anything for me to access it like setName('<value>'). For lists, would I just have to say listName('<num_index>')?

C++/OOP Associations model and database

Edit: I called it association because in my head it should be this, but it seems that I implement it as an aggregation... This can be also discussed...
Context
What you learn in IT is that when you do associations, you should use pointers.
For example: You have 2 objects: Person and Movie. One Person can do several Movie and one Movie can be done by/with several Person. You would then have:
class Person
{
public:
Person::Person();
int id;
vector<Movie*> movies;
};
class Movie
{
public:
Movie::Movie();
int id;
};
main()
{
Person person;
Movie *movie = new Movie;
person.movies.push_back(movie); // With a setter it would be better but...
}
or something like this (please correct me if I do something wrong =D)
Where the troubles appear
Now you have many persons and movies and you want to save it somewhere: in a database.
You get your person
You get all the movies it is associated with in order to construct the whole object.
But how do you get them?
Do you reconstruct a new pointer of Movie for each Person concerned that you associate ?
You lose then the association property that allow the objects to be linked but live their own life.
Do you load all the database in RAM and... ok forget this
What is the way to do it cleverly? What is the proper way given by documentations?
I'm interested in simplified/pseudo code as examples, dissertation... Thx a lot !
Your question is very broad, and there's a number of approaches, how to bind database tables (and represent their foreign key connections).
It's not really only how to represent/handle that kind of Domain Model snippet, you're presenting in your code sample here.
#Martin Fowler provided the EAA pattern catalogue you could reasonably research, and apply appropriate patterns for these kind of object <-> relational mapping problems you address.

Discriminator column not set in newly persisted entity

I have a base class entity that looks like this:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name = "IDTYPE",
discriminatorType = DiscriminatorType.STRING,
length = 12)
public class ProtoObject implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String idtype;
// more columns
I have a number of sub-classes of this that I build and persist. However I have found that even though idtype column gets set to what I would expect in the data base (checking with a separate DB browser tool) the Java objects idtype property does not get set for those object that the EntityManager has in its cache.
If I do a find of objects through the EntityManager, the most recently persisted objects appear to have idtype blank! If I close the application and re-open it the data appears OK.
This is a JSF 2 application using EclipseLink 2.3.2.v20111125-r1046.
Is this a known problem and can anyone suggest a work-around?
You can update cache after persisting:
this.entityManager.persist(protoObject);
this.entityManager.flush();
this.entityManager.refresh(protoObject);
You didn't set the attribute when you created the object to reflect what you wanted pushed to the database. You need to set the field to keep it consistent in the cache as JPA Entities are treated as regular java objects and won't fix things for you. Or after persist you can flush the changes them refresh the object to have the field populated with what is in the DB

How to efficiently count related rows within a model using Doctrine2

I'm pretty new to Doctrine and wondering how to efficiently calculate the number of related objects there are for a particular model object.
I read here that it's not a great idea to use the entity manager within models so I'm wondering how I would query the database to find out without lazy loading all of the related models and doing a count().
I haven't really found a great answer yet, but it seems like this is a pretty fundamental thing?
For example
class House
{
/**
* #var Room
*/
protected $rooms
public function getRoomCount()
{
// Cant use entity manager here?
}
}
class Room
{
// Shed loads of stuff in here
}
Doctrine 2 will get counts for you automatically as association properties are actually Doctrine Collection objects:
public function getRoomCount()
{
return $this->rooms->count();
}
If you mark the association as eager, Doctrine will load the rooms whenever you query for house entities. If you mark them as lazy (the default), Doctrine won't load the rooms until you actually access the $this->rooms property.
As of Doctrine 2.1 you can mark associations as extra lazy. This means that calling $this->rooms->count() won't load the rooms, it will just issue a COUNT query to the database.
You can read about extra lazy collections here: http://www.doctrine-project.org/docs/orm/2.1/en/tutorials/extra-lazy-associations.html