How to handle EntityNotFoundException in Spring Data JPA (or just standard JPA 2) - jpa-2.0

I am in the process of cleaning a database. These process involves changing the format of certain fields and getting rid of some data integrity issues.
I developed a program with Spring Data 1.1 to process the records in batches. The problem arises with 2 entities in a #OneToOne relationship. The record for Entity B does not exist although Entity A has a reference to it. My job is to clear the reference to Entity B if that is the case.
The question is: should I pre-process the data to clean this or can I adjust Spring Data or JPA settings to put null in the field if the Entity is not found?
It is "normal" - with this data - to have a FK in Entity A that does not exist in Entity B, so I want to handle this in my code and not have to pre-process the data with an additional step or other tool. The data will be arriving in batches so any pre-processing makes things more complicated for the user.
In summary, I want Spring Data to set the field to null and continue the process instead of getting an org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find....

Perhaps you are looking for the #NotFound annotation?
Here is a post that talks about it.

I have had the same problem because my orm mapping has a wrong #One-to-one unidirectional relationship.

Related

Can I return DTOs in Repository design pattern?

Repository is like a collection of domain objects. So it should not return DTOs or anything that is not a domain object.
But, Suppose your domain model has 20 fields with large amount of data and you want to use only 2 fields here, you have to fetch the whole row first and then map it, which is very inefficient.
It depends. If you are modeling with DDD and CQRS then you should return Aggregates for commands and ViewModels for queries. You can split repos in reads and writes, where reads are used for serving views for example, or REST APIs, case in which you would have DTOs and not ViewModels, thus you only return the data (fields) that you need from the query.
In the write stack you should have a single method that returns, and the return type should be the Aggregate of that specific repository (use lazy loading if you don't want to load all related child collections)
TAggregate GetById(object id)

How to persist a complex nested object with Doctrine?

I'm migrating the DBAL of a Zend Framework 3 application to Doctrine. The data retrieving part is completed and working. Now it's the turn of the data saving.
There is a more or less complicated (about 10 level) dynamic structure of objects/entities. Then there is a structure of Fieldsets, that reflects the objects' structure. The hydrating of the Form's data to the nested object/entity is a matter of Zend\Form. So I get from the Form a complete object ready for saving.
Currently the saving is working as follows:
There is a structure of Mapper classes, that reflects the objects'/entities' structure. Means: Every entity has its Mapper. Every Mapper knows its "sub-Mappers". If the entity FooEntity processed by a mapper FooMapper has a property of type BarEntity, the FooMapper#save(...) will call the BarMapper#save(...) to persist it. Then if the entity BarEntity processed by a mapper BarMapper has a property of type BuzEntity[], the BarMapper#save(...) will call the BuzMapper#save(...) in a loop to persist the data. And so forth...
How to replace all that hardly maintainable stuff by using Doctrine's functionality and handle this cascading saving in a more elegant way?
Some saving functionality will be eliminated by using cascade={"persist"}. But my problem is, that for all the remaining parts I have no better ideas than keeping the hierarchical Mappers structure just replacing of the Zend\Db's insert(...) and update(...) by the Doctrine's persist(...).

merge in doctrine 2 not working giving error

I am trying to update a row in a table. I am using doctrine 2 ORM. I am trying to update a row using merge(), which is said can be used to update a row. But it gives a error saying
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
I am new to doctrine 2. please suggest what can i do?
When to merge
First off: You only need $em->merge() when you have an entity that isn't managed by the EntityManager, but you want it to be. A common use-case is when you have a serialized entity, and want the EntityManager to start managing it.
So merging entities is not directly related to updating entities in the database.
If you simply find (using $repo->find*()) an entity and make changes, calling $em-flush() is sufficient. The entity is already managed by the EntityManager and there's no need to merge it.
How to merge
A common mistake when using $em->merge() is that the passed entity itself becomes managed. This isn't true, $em->merge() returns a new object that represents the managed entity.
$managedEntity = $em->merge($detachedEntity);
After this line of code, $detachedEntity is still detached (meaning it still isn't managed by the EntityManager). It's $managedEntity which you can start using to make changes.
Your code
Given the code you've put in the comments, you probably want to do something like this:
$user = $entityManager->getRepository('User')->find($_REQUEST['id']);
$user->setName($_REQUEST['name']);
$user->setPassword($_REQUEST['pass']);
$entityManager->flush();
PS: It looks like you're saving the the plain-text password in the database. That's never a good idea.

Usage of Id='' in EAI Siebel Adapter Query

Requirement: I am suppose to use an existing Integration Object for my requirement. As this IO consists of ICs that I do not need in my requirement, I would like to avoid them in my IO query output.
I observe that passing Id = '' returns no result in Siebel 8.0. Can I use it as a feature and pass SearchSpec => [Integration Component.Id]='' to EAI Siebel Adapter query to suppress ICs that I don't want in output?
How good is this query Id=''? Will Siebel ignore this query completely? or will it attempt and return no output?
As per my understanding Siebel ignores the query where row_id is passed as ''
(Not true for siebel 6.0) Please share your opinion.
Not sure of using Id = '', when you club the condition with other conditions, Siebel might try to find actual matching records. Also , not sure if future upgrading will keep the same system.
If yours is the only code using the IO, you could straightaway inactivate the ICs you dont want.
If you are unsure of IC inactivation, best way should be to a DatMapper. Set up an EAI Datamapper, source and target IOs of same name. In this datamapper, map only the ICs you need. After querying from EAI Siebel Adapter, send your output to this DataMapper.
Siebel will keep only the ICs mapped and remove all the rest.
Since this is a non-repository change, you can modify the DataMapper in future too.
Hope this helps !
Answering it myself with my opinion..
As per my understanding, querying with Id='' still queries the database for row_id = ''. Including this in IO query reduces the query scope to the parent's context..
Though this won't improve any performance, IO query output looks cleaner.
Update: I'm using a Indexed column based field Id (ROW_ID) with search spec as "[Id] IS NULL". It's a next to impossible case in database having ROW_ID = NULL, unless it's intentionally and manually updated. Again no one would do it unless really wants to messup that data .. because without ROW_ID record is literally invalid..
Adding a null query to the IC will inherently result in an empty property set for the IC in question. But if you don't need the IC, and the ICs in the IO are not hierarchically connected (no hierarchy key )(eg- independant BCs with same base table in the same BO), you just have to remove the IC mapping in the datamap editor and the IC wont show in the IO propset

Doctrine 2 How to set an entity table name at run time (Zend 2)

I'm building a product with Zend 2 and Doctrine 2 and it requires that I have a separate table for each user to contain data unique to them. I've made an entity that defines what that table looks like but how do I change the name of the table to persist the data to, or in fact retrieve the data from, at run time?
Alternatively am I going to be better off giving each user their own database, and just changing which DB I am connecting to?
I'd question the design-choice at first. What happens if you create a new user after runtime. The table has to be created first? Furthermore, what kind of data are you storing, to me this sounds like a pretty common multi-client capabilities. Like:
tbl_clients
- id
- name
tbl_clientdata
- client_id
- data_1_value
- data_2_value
- data_n_value
If you really want to silo users data, you'd have to go the separate databases route. But that only works if each "user" is really independent of each other. Think very hard about that.
If you're building some kind of software-as-a-service, and user A and user B are just two different customers of yours, with no relationship to each other, then an N+1 database might be appropriate (one db for each of your N users, plus one "meta" database which just holds user accounts (and maybe billing-related stuff).
I've implemented something like this in ZF2/Doctrine2, and it's not terribly bad. You just create a factory for EntityManager that looks up the database information for whatever user is active, and configures the EM to connect to it. The only place it gets a bit tricky is when you find yourself writing some kind of shared job queue, where long-running workers need to switch database connections with some regularity -- but that's doable too.