Pogrammatically get foreign keys for a table in jOOQ - java

Is there a way to programmatically list all the Fields which are a Foreign Key in jOOQ? It generates a lot of static constants to foreign keys, but there is no good way to programmatically access these.
Example, I have a table Orders with a foreign key field customer_id. In jOOQ, say I have a reference to said table object for Orders, there does not appear to be a way to programmatically get a reference to the customer_id jooq field object. So my only solution now is to manually make these mappings somewhere using a literal map datastructure. Seems like jooq would have been able to do this for me, am I missing something?

There are many ways to navigate the jOOQ meta model. Your description isn't complete, but I'm assuming, you would want to do something like this:
for (ForeignKey<?, ?> fk : ORDERS.getReferencesTo(CUSTOMER))
for (Field<?> fkField : fk.getFields())
System.out.println(fkField);

Related

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.

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

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

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).

How to find relationship between two tables?

In the SQL, we need to write a lot, multi-level join. but the problem is, we don't now how to connect those tables?
For example, Table_A reference Table_B, Table_B reference Table_C using foreign key. How to get all this relationship route map? Do we have a free open souce tool to get relationship between ANY two tables if applicable?
I prefer Java code.
You can use SQL Power Architect to obtain a data model by reverse engineering a database. The Community Edition is capable of doing it.
I maybe you mean how to get foreign key from metadata. Basically foreign keys defines realations.
Here is an example how to get foreign keys from jdbc metadata:
http://www.java2s.com/Code/Java/Database-SQL-JDBC/GetForeignKeys.htm
Also you can use hibernate tools to reverse engineer database to domain entities. Where you can clearly see relations.
java.sql.DatabaseMetaData interface exposes meta information about the database. Specifically this method exposes foreign key relationships:
public ResultSet getCrossReference(String primaryCatalog,
String primarySchema,
String primaryTable,
String foreignCatalog,
String foreignSchema,
String foreignTable)
throws SQLException
Java doc:
Retrieves a description of the foreign key columns in the given foreign key table that reference the primary key columns of the given primary key table (describe how one table imports another's key). This should normally return a single foreign key/primary key pair because most tables import a foreign key from a table only once.

ejb3: mapping many-to-many relationship jointable with a simple primary key

often in books, i see that when a many-to-many relationship is translated to a DB schema, the JoinTable gets a compound key consisting of the primary keys of the tables involved in many-to-many relationship.
I try to avoid compound keys completely. So i usually create a surrogate key even for the JoinTable and allow the database to fill it up by trigger or whatever feature a database has for incrementing primary keys. It just seems like a much simpler approach.
the only issue i can think is that, there are chances of duplication of foreign key pair in the JoinTable. But this can be avoided by a simple query before a row is inserted in the JoinTable.
Since books always use the compound keys approach, i wanted to know if, there are any negative effects if i use simple one column surrogate keys for the JoinTable?
In my opinion, using a single primary key is a bad idea.
First, as you said, a single primary key won't ensure unicity in the database. Sure, you can check this at runtime using a simple query, but this is costly, and if you forget just one time to do your check query, you can put your database in an inconsistent state.
Also, I think that using an additional column for the primary key is, in this case, not necessary. You don't need to identify relationships by a unique primary key, since the relationship is already defined by two unique keys: the primary keys of your two tables. In this case, you'll have unnecessary data, that will add complexity to your data model, and that you'll probably never use.
I try to avoid compound keys completely.
Huh? Why? I mean, why totally avoiding them? What's the reason behind this?
So i usually create a surrogate key even for the JoinTable and allow the database to fill it up by trigger or whatever feature a database has for incrementing primary keys. It just seems like a much simpler approach.
No offense but we don't have the same definition of simplicity then. I really don't see where it is simpler.
The only issue i can think is that, there are chances of duplication of foreign key pair in the JoinTable. But this can be avoided by a simple query before a row is inserted in the JoinTable.
First of all, don't use a SELECT to check uniqueness (you can have a race condition, a SELECT without locking the whole table won't guarantee anything), use a UNIQUE constraint, that's what UNIQUE is for.
And lets imagine one second that a SELECT would have been possible, do you really find that simpler? In general, people try to avoid hitting the database if possible. They also avoid having to do extra work.
Since books always use the compound keys approach, i wanted to know if, there are any negative effects if i use simple one column surrogate keys for the JoinTable?
So you mean something like this:
A A_B B
------- ------------------ --------
ID (PK) ID (PK), ID (PK)
A_ID (FK),
B_ID (FK),
UNIQUE(A_ID, B_ID)
Sure, you could do that (and you could even map it with JPA if you use some kind of trigger or identity column for the ID). But I don't see the point:
The above design is just not the standard way to map a (m:n) relation, it's not what people are used to find.
A_B is not really an Entity by itself (which is what the model somehow suggests, see #1).
The couple (A_ID, B_ID) is a natural candidate for the key, why not using it (and wasting space)?
The above design is not simpler, it does introduce more complexity.
To sum up, I don't see any advantage.

Categories

Resources