EJB Session Bean / Client Hibernate Session interaction? - java

in a school project we are using an EJB Session Bean,
this EJB offers simple services such as add, delete, modify, findAll, findbyId. Such methods are implemented using hibernate 4.0 (add -> saveOrUpdate, modify -> saveOrUpdate...) and are available for the client
I have two classes : Game (id, description, category) and Category (id, title).
A category has also a set of games.
The ids are generated using the identity generator. The databased used is mysql.
In the client
A form is used by the application user to fill out informations about a game (description and category ) In the controller I use the method findById to get the category that the user chose, then I create a new game with this category and I save it (using SaveOrUpdate)
first problem that I notice : the id is generated correctly in the EJB and the game passed is modified but back in the client the game doesn't have an id (I guess passing objects between a client and a EJB is not by reference) Can anyone confirm it ?
second problem : when the game is save I tried to add this game to the set of the category and update this category (using also saveOrUpdate). I get the exception org.hibernate.NonUniqueObjectException:
a different object with the same identifier value was already associated with the session
which I don't understand
Can anyone help me ?

For the first question, it sounds like the ID isn't being sent back to the client, or being stored with the controller .
You could send it back to the client by adding it to the URL, ie, in the return from the client call add "?id=" + newGameId
With this you can have the value populate back into the controller with setters and getters for an id field;
long id;

Related

How can I insert data into the database when an entity is created?

I'm creating a website for a school project which uses spring for the backend. I'm trying to insert data into the database when new data is saved to a specific table.
I've tried using #HandleAfterCreate and #PrePersist, but neither worked. I'm not very experienced with spring. The teacher told us to use it and now I don't know what do.
#HandleAfterCreate
public void handlePersonBeforeCreate(Person person){
logger.info("Inside Person Before Create....");
Set<Qualifikation> qualifikationen = new HashSet<>();
kompetenzRepository.findAll().forEach(kompetenz -> {
Qualifikation qualifikation = new Qualifikation();
qualifikation.setAusmass(0);
qualifikation.setKompetenz(kompetenz);
qualifikation.setPerson(person);
});
person.setQualifikationen(qualifikationen);
System.out.println(person.getDisplayName());
}
The code should set a person's "Qualifikation" to a default value when the person is inserted (via OAuth login). It should have every "Kompetenz" with a value of 0 by default. Kompetenz has a 1 to n relation to Qualifikation. If you need more information please ask me.
It looks like you're trying to have access to the repository layer of your application inside an entity. This is generally not a good idea, as the entities should only know about the data they hold, not the other application components.
In this particular case it would be wise to use a #Service class with a method that you can call to insert the data into the database. In the method you could then insert any other entities as well. Let your repositories be fields of the service and make them #Autowired.
I think you need to enable JPA auditing . It can be enabled in Spring by add #EnableJpaAuditing to your persistence configuration. This tells Spring to listen JPA entity lifecycle events and call the annotated methods in appropriate places.
Also I think you should make the callback method private if it is meant to be called only when persisted (#PrePersist).
See details here. In this article is also presented entity listeners which might also be a good solution when dealing with multiple entities having a need for same pre-persist functionality.
I think you should create a service class, a repository class and an entity which will be stored through repository. The logic of getting all inner elements and filling it with default value is to be written in service and not a good idea to write in entity class.
If you need any help regarding it, let me know .
Welcome to community!!

spring data rest - Create a relationship oneToOne and create the ressource

I'm testing spring data rest and I would like make a post on a relation entity.
For exemple :
I've two classes :
one two
----- -----
field field
#OneToOne
fieldTwo
how can I instantiate two ?
when I do post on /one
{
"field":"field",
"field2": {
"field":"field"
}
it doesn't create a field2
when I do post on /one/{idOne}/twos:
"field2": {
"field":"field"
}
it does nothing.
Does somebody have more informations ?
I didn't find any informations about this.
Thanks
Gegko
If I understood correctly you're trying to create records/entities with association using Spring Data Rest.
In Spring Data Rest when you POST for an entity, it won't create automatically the associated entity. instead, you will have to create each entity separately by yourself using rest.
If you want to create entities with association using REST, all you have to do is first create the not owning entity (the entity which doesn't hold the foreign key). when you do that you'll have its rest URL.
the second step is to take that URL and to put it as a foreign key when you try to save the second entity.
Here's an example:
POSTing a #OneToMany sub-resource association in Spring Data REST

Spring mulitple rows with hibernate bean

We are migrating to spring & hibernate from struts1.x and JDBC.
Facing issue while adding multiple rows in jsp (like mapped properties in struts1.x) based on user preferences (Ex: Adding/deleting employees to Manager) in spring.
In service layer, getting Manager Object (as persistent object returned by hibernate )then displaying manager object in JSP. Employee row will be deleted by using java script/jquery from html form by user delete action, upon form submission spring does not delete in the respective employee from the list of employees of Manager object (model attribute). I have worked on some examples without hibernate where the object is being deleted from the list and works well but not in the hibernate prepared object.
ex: lets say Manager object have 3 employees as List when displaying on screen, when user will delete one employee row and submitted then spring needs to populate the Manager object with two employee objects as list since one employee is deleted by user in UI.
I suspect that, this behavior with PersistentBag implementation of Hibernate?
Anybody experienced this problem earlier? Any ideas would be greatly appreciate.
It might depends on how the pojo is declared..
Sure you are deleting a manager, but how is the manager connected to the employee?
If on the manager you have a Employee Object, you should have
#OneToOne(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.EAGER)
#Fetch(FetchMode.SUBSELECT)
#JoinColumn(name="EMPLOYEE_ID", nullable = false)
private Employee employee;
This way, if you delete the manager object, it will cascade delete the Employee object...
Either your "cascade" is enforced via db, or it must be enforced via annotation.. if you're not doing either, of course nothing will happen...

Persisting with Entity Manager into MySQL on a table with auto increment PK

I am following the NetBeans E-commerce tutorial - on the 9th Tutorial which is about Integrating Transnational Business Logic
Where they show how create the OrderManager class with placeOrder() Method - and the method is transactional which involves three tables - first customer, then customer_order and finally orderedItem using em.persist().
but the em.persist() method is not persisting for customer - but it will persist for customer if I manually supplied the customer id manually into the code (hard code).
but for the customer_order it will not persist even after persisting the customer by manual id provision and using em.flush();
I googled and couldn't seem to find way out. P.S. The Entity class is generated with Netbeans wizard - and the id generation strategy IDENTITY
The em.persist() was not persisting because the #NotNull annotation on the id fields was not allowing null - as I am working on Netbeans.
so removing those #NotNull or commenting them out on the entity class gets the job done.
infact I learned this fact from the last post of the following link.
Hibernate Auto Increment ID

Expressing Audit functionality with JPA annotations

I'm in the middle of fumbling around with JPA. I've so far successfully created an entity representing the user data and a stateless bean for the access to the user data.
The data the users can work on is like this (SQLFiddle link):
CREATE TABLE data
(
email character varying(128) NOT NULL,
data character varying(128) NOT NULL,
lastchange timestamp NOT NULL,
CONSTRAINT email_data PRIMARY KEY (email,data)
);
The idea is to save the unaltered, current version for all users with an empty email key. Then, when a user alters the data and creates an auditable version, the email field is filled with the users email. This way, each user can alter their copy of the data. The merging is a problem for a later date and not part of my question.
Now, I have the entities already in place. I created a stateless bean to load/save/find the data records by using the EntityManager. The logic to load the user specific version first, then load the unaltered version if the user has no user specific version still eludes me.
Consider this part of the bean:
#Stateless
public class DataBean {
#PersistenceContext(unitName = "authPU")
private EntityManager em;
public List<DataEntry> findAll() {
TypedQuery<DataEntry> query = em.createQuery("SELECT d FROM data d", DataEntry.class);
List<DataEntry> list = query.getResultList();
return query.getResultList();
}
...
}
How do I inject the user information into this class? I need to get the data for the current user first, then get the data for all users if there's no user-specific data available.
You could use standard EJB authentication. Then you can call SessionContext.getCallerPrincipal() in your session bean to get a user ID. Use this user ID to query the database.
In this case you have to add another column to your table (containing the user ID), if the authentication user ID does not equal the email address.
Far simpler (but less elegant) is to add the email address to the arguments of your EJB service method: Just make it part of the public API.

Categories

Resources