JPA: InvalidStateException Error + Composite Key/EmbeddableId/Sequence Generated IDs - java

I currently have a schema set up with my database and Java Application using OpenJPA that works most of the time, but sometimes I get the error for a few users:
org.apache.openjpa.persistence.InvalidStateException: Attempt to set column "table1.ID" to two different values
table1 actually has a composite Key (two values) and each value in that key is a foreign key to another table. I used RSA (Rational Software Architect) to set up the entities for me (generated code). It set up a PK class (using #EmbeddableId to reference the PK class) in the Entity class for table1, and then two #ManyToOne relationships in the same table1 Entity class (and also in the entity classes that those columns reference) since they are foreign keys
Now, as I mentioned above, each value in the composite key is a foreign key. Well, each of those foreign keys is actually generated using an outside Sequencer in their own entity classes. I am using DB2 and using #GeneratedValue on the columns (i.e. the IDs in table2's and table3's entity classes). I use strategy=GenerationType.SEQUENCE also for each.
Again, everything works USUALLY but not 100% of the time and I'm unsure why. I have gotten rid of this error by wiping out everything and resetting the Sequence Generators, but I know this is definitely not a solution. Could it have something to do with the fact that the two Composite Key values in the database are foreign keys to columns which were generated using a sequence, but the PK entity might not know?
I have noticed too that it only works for users who have a record in the Users table (one of the foreign keys mentioned above is to a Users table, while the other FK is to another table). What happens, if a user is not in the table, it creates one, something like:
User newUser = userManager.getNewUser();
newUser.setName(..);
newUser.setEmail(..);
...
When it's done, the PK class I mentioned above has a new instance of that created, which is then called into another table. The ID from the user above is passed into the PK. Like:
PK newPK = pkManager.getNewPK();
newPk.setAID(newUser.getID());
Has anybody run into this? Any solutions?

Sorry, fixed the problem. I went through my code and realized I had forgot to refactor one line of code (change in data model).

Related

How to represent table with nulls in Spring Data JPA?

What should I do to represent this table in Spring Data Java Persistence Application Programming Interface (JPA)?
The table is specific because it has no primary key and every column in the table can have nulls, and it is read only.
In entity class I can not simply annotate a single column with #id because there is no column with unique values.
I can, of course, create composite virtual primary key in entity class by annotating every column with #id, and that works, but only if there are no nulls in the row. So if I select row(s) with all columns not null then this works. But if one or more columns contains null, Spring is not able to extract that row from table, and instead returns simply null for entire row rather than returning an entity object with only the appropriate field null.
Please do not say "just add id column to the table" because table is read only for us. My company was negotiating for more then a month just to get the read rights to the table! I can not simply add id field in the table.
What else can I do in this case? Other than manually executing a query and extracting the result. Can I somehow fake the id field to make Spring happy? id field is not important for our application, we will never filter the table by id, so it can be whatever makes Spring happy as far as I am concerned.
I don't think there is a way to do that.
Just get a NamedParameterJdbcTemplate injected and query away.
A central premise of JPA is that you can load data from a bunch of tables, edit the resulting object structure and JPA will take note and mirror the changes to the data in the database.
If you don't have anything to use as an id you wouldn't know which row to update. So this whole approach kinda fails to work.
You can use #EmeddedId with an ID you create. Set the ID field either #Transient or static so it won't affect persistence.
In the below example I use the UUID static method .randomUUID() to generate the ID.
So put this into your #Entity and you will get every row regardless of nulls. Inserts will work just fine too (depending on how you disambiguate your rows).
#EmbeddedId
static UUID uuid = UUID.randomUUID();

Telosys code generation fails when the table has foreign key

I have a issue when generating code using Telosys.
After configuring all the information, when I click on Create model
I get the following issue:
If I remove foreign key from table and click Create model then this works fine.
It has become like have to remove the foreign key from table and Create model and then add back the foreign key again.
How to do this without removing foreign key constraint?
PS: I just use this tool to create Spring JPA entity.
After looking in the source code it seems that the table name referenced by the FK is not found in the model.
May be due to upper case / lower case difference in the table name. For example a FK referencing the "Foo" table instead of "FOO" (or vice versa).
You can check the table names retrieved from the database with "Get tables" in the "Meta-data" tab. Use "Get foreign keys" to check the Foreign Keys :
I guess you skipped configuration. You can customize existing templates in order to generate jpa DAO
the templates available on GitHub : https://github.com/telosys-templates-v3

JPA map view with no primary key to an entity

I've got a database view with no primary key. It has a set of columns which uniquely identify a row in the view, but three of those columns can be null. I've tried creating an entity with a composite primary key based on those four columns but when retrieving data from the view I get this error:
The primary key read from the row ... during the execution of the query was detected to be null. Primary keys must not contain null.
Is there something I can do, for example, adding an automatically generated column when defining the view?
JPA Specification says that an Entity class must have a unique, immutable ID.
Logically, if it does not have any primary key, it can't be called entity. What you can do instead is create a POJO representation of your VIEW, then execute a SQL Native query, then map the result set to your POJO.
Here's a sample using #SqlResultSetMapping/#ConstructorResult
http://www.thoughts-on-java.org/result-set-mapping-constructor-result-mappings/
Not all entities have PKs that fit the definition of JPA. There are a couple of ways around it, all of them hacky.
1) modify the view to combine the fields (substituting nulls with sensible values) into one field, and map that as a PK
2) use the attribute converter functionality to substitute nulls with sensible values, then you can map the composite PK.
3) use RowID as a PK (this is ok only if you don't depend on the PK for anything long term, as RowIDs are not guranteed to stay consistent between runs.
I'm sure there are other similar workarounds, but I've used 1 and 2, and explored using 3.

Mapping a single parent column table to multiple columns of a child table using JPA and Hibernate

I am trying to map a single parent primary key to multiple child foreign keys. I have a User table which holds users of different types e.g their are users of type admin, type worker, and type client. I then have a child table called job. A single job record holds reference to an admin, worker, and client primary keys. I tried mapping this sinario in hibernate but hibernate gave me an error saying I cannot map a single column to multiple columns. I have attached an email of my table design.
You can keep the adminId, workerId and clientId references in your Job POJO, and then configure 3 many-to-one tags as properties of it, all referring to the same table. I think this would work, but I cannot test it right now. Can you post the XML you tried to use, or the Java code, if you were using annotations? Even better, can you post the stack trace?

JPA Composite Key for one Table and a Primary Key for another Table - Possible?

Is it possible to have both a composite key and a primary key in the same Domain Model (Entity Class) so that some tables (queries) are joined using the composite key and other tables (queries) are joined using the primary key?
I'm dealing with legacy applications and I have limited access to changing the underlying database. Some of our queries are expecting a single row result but are getting many rows because of flaws in our database design. We can fix this problem by introducing a composite key to one of our Domain Models but doing so will affect many (many) other components that rely on the original primary key.
From my understand of JPA and the reading I've done so far on this matter I do not think this is possible but I thought it would be worth a shot to reach out to others who may have had a similar problem.
The table has only one primary key, so you have no options to choose which primary key to use. Also, i can't understand why you going to have differences between database original model and JPA. Actually, getting single row instead of many rows is where clause's task.
You said some of your queries fails after adding composite pk, so may be you just made your composite pk in wrong way?
Anyway, here is nice example or implementation composite pk, may be it will help you:
Mapping ManyToMany with composite Primary key and Annotation:
Maybe you should give a different look at your problem.
If your queries are returning multiple and different rows, then you should be able to resolve this using a more specific WHERE clause;
If your queries are returning multiple and equal rows, you should try the DISTINCT clause inside your query, example:
SELECT DISTINCT e FROM br.com.stackoverflow.Entity e

Categories

Resources