I am new to JPA and databases in general. I was trying to generate entities from tables using JPA tools in Eclipse. There are a number of tables and I am trying to generate entities for all of them at the same time. The JPA tool gives me the following options for Key-generator.
I looked around on Google a bit but could not find much that addresses all the options. What do the options mean?
The JPA specification document provides answers in section 11.1.20, on pages 449 and 450:
The GeneratedValue annotation provides for the specification of
generation strategies for the values of primary keys. The
GeneratedValue annotation may be applied to a primary key property or
field of an entity or mapped superclass in conjunction with the Id
annotation.
The use of the GeneratedValue annotation is only required to be
supported for simple primary keys.
In case you are not familiar with the Id annotation, here is a quick explanation by Vlad Mihalcea from t/his blog post:
The #Id annotation is mandatory for entities, and it must be mapped to
a table column that has a unique constraint. Most often, the #Id
annotation is mapped to the Primary Key table column.
The types of primary key generation are defined by the GenerationType enum:
TABLE, SEQUENCE, IDENTITY, AUTO
The JPA spec gives details on those types as follows:
The TABLE generator type value indicates that the persistence provider
must assign primary keys for the entity using an underlying database
table to ensure uniqueness.
The SEQUENCE and IDENTITY values specify the use of a database
sequence or identity column, respectively. The further specification
of table generators and sequence generators is described in sections
11.1.48 and 11.1.51.
The AUTO value indicates that the persistence provider should pick an
appropriate strategy for the particular database. The AUTO
generation strategy may expect a database resource to exist, or it may
attempt to create one. A vendor may provide documentation on how to
create such resources in the event that it does not support schema
generation or cannot create the schema resource at runtime.
A well-established and recommended strategy is to chose the SEQUENCE strategy, if that is supported by the database management system.
Note well, that strictly speaking, there is no NONE strategy defined in the JPA spec. The corresponding option in the select one menu, depicted in the screenshot, simply expresses that "none" of the four regular types shall be set. This seems to be a fallback to indicate you don’t have chosen your strategy for now. Still, you should pick one from the regular ones.
Related
I have to use Orion (NGSI v2), and I have a question about the name of entityId of my context;
could I use a simple ID or URN (like NGSI-LD spec)?
What is the best practice?
Thanks a lot
From a NGSIv2 point of view, any entity ID that complies with the identifiers syntax restrictions is valid.
Having said this, in general the simpler entity ID, the better from an integration point of view. For instance, if you are persisting context data using Cygnus sink for PostgreSQL, note that PostGresSQL could use tables which name includes the entity ID (for instance, if the dm-by-entity-database-schema DM is used, see this reference).
Thus, better to use simple entity IDs than URN-like entity IDs, from my point of view.
I think it is better to use URIs for your entities, your path to Linked Data will be smoother. The problem with table names should be fixed by the data storage component for instance by calculating a hash of the URI and converting it to the proper alphabet supported by the database concerning table names ...
So I'm creating a database model using Entity Framework's Code First paradigm and I'm trying to create two tables (Players and Teams) that must share a uniqueness constraint regarding their primary key.
For example, I have 3 Players with Ids "1", "2" and "3" and when I try to create a Team with Id "2", the system should validate uniqueness and fail because there already exists a Player with Id "2".
Is this possible with data annotations? Both these entities share a common Interface called IParticipant if that helps!
Txs in advance lads!
The scenario you are describing here isn't really ideal. This isn't really a restriction on Entity Framework; it's more a restriction on the database stack. By default, the Id primary key is an Identity column, and SQL itself isn't really supportive of the idea of "shared" Identity columns. You can disable Identity and manage the Id properties yourself, but then Entity Framework cannot automatically build navigation properties for your entities.
The best option here is to use one single participant table, in a technique called "Table Per Hierarchy", or TPH. Entity Framework can manage the single table using an internal discriminator column. Shared properties can be put into the base class, and non-shared properties can be put on the individual classes, which Entity Framework will composite into a single large table in the DB. The main drawback to this strategy is that columns for non-shared properties will automatically be nullable in the database. This article describes this scenario very well.
The more I try to come up with a solution, I realize that this is an example of the XY Problem. There is not really a good solution to this question, because this question is already a proposed solution. There is a problem here that has led you to create an Interface which you suggest requires the entities which are using the interface to have a unique Id. This really sounds like an issue with the design of the Interface itself, as Interfaces should be agnostic to the entity they are applied to. Perhaps providing some code and showing what your problem actually is would be helpful, since the proposed solution you are asking how to implement here isn't really practical.
I am creating a kind of social network and I have users that can follow other users. So I have an entity like:
#Entity
public class FollowedUser{
#ManyToOne
private User user;
#ManyToOne
private User followedUser;
//more fields
...
}
I cannot have a ManyToMany relationship as I have more fields in my FollowedUser entity. Now, the questions I have are:
Should I use a compound key or a generated id (surrogate key)? I have read the following links (1, 2, 3) about the topic where a surrogate key is suggested, but I don't know if they apply to my concrete case (where my compound key would be composed of two surrogate foreign keys). Also here (4) it says "Composite primary keys typically arise when mapping from legacy databases" so I suppose they are discouraged.
In case I should use a compound key, I don't know if I should use #IdClass (as recommended here 5) or #EmbeddedId (as recommended here 6) or any other option. Although I suppose it doesn't matter.
In case I should use a surrogate key, I don't know how to still make impossible to have the compound candidate key repeated. I have read here (7) about unique indexes but I don't know if it is the correct workaround to that problem.
1. I recommend using surrogate keys. I find it helpful to separate the database identity of a record from it's business identity. If the two concepts are mixed, it may be cumbersome to model them right and to remodel them later. You reference some good answers, so you are probably aware of the major up- and downsides, no need to reiterate them here. One additional point is that you can rely on the surrogate key like UUID to implement equals and hashCode properly. Implementing those for a composite keys to play nicely with both collections and the db can be tricky.
As to your use case, a connection between users can be viewed as an entity of it's own and have a autogenerated surrogate PK. You can enforce the uniqueness of the business key attributes in the DB, see pt.3.
2. AFAIK, deciding between EmbeddedId and IdClass is mostly a matter of taste. I prefer
IdClass, since it avoids having to add navigation when querying id attributes:
... WHERE a.id.attribute = :att with EmbeddedId vs.
... WHERE a.attribute = :att vs. with IdClass
I do not find the argument you link 6 convincing. Composite keys tend to consist of the most characteristic attributes of the entity. To hide them away in a different class because they happen to be used as the DB key seems awkward to me.
3. Unique indexes look like a good way to guarantee uniqueness of a combination of attributes. You may want to read this answers, there is a small example.
If you are not yet working with JPA 2.1, you might want to use unique constraints, as explained here.
This shows how to set the identity seed.
EF Code First - how to set identity seed?
dataannotations set identity seed value on Primary Key with code first
How do you set the identity increment value using code first?
There is no way to do it.
None of the ways to configure the entities (conventions, attributes, fluent API) allow to do that. You can neither implement it using custom conventions (in short, a custom convention checks the name, attributes, type, containig type or whatever of a column, and then uses fluent API to config the column, or entity). At least up to EF 6.1.1.
The only way to manipulate an identity in SQL Server is by using DBCC CHECKIDENT, but this only allows to change the seed value, and not the increment.
If you want to change the increment you have to drop the column and create it again in the database initializer Seed method. The problem is that you have to drop and create all the keys (PK or FK) related to this column. (This applies up to SQL Server 2014)
You can have a look at this answer where I explain the possible solutions, alternatives and work arounds, which work, and which don't, and a link to vote to get this included in a future release of EF.
I know how to mark a group of fields as primary key in ADO.NET entities but i haven't found a way to declare unique constraints or check constraints.
Is this feature missing on the designer or on the framework?
Support for unique keys/constraints does not exist in ADO.NET Entities in v4.0, see the answer to "one-to-one association on a foreign key with unique constraint", where Diego B Vega says:
I know for sure we haven't added
support for unique keys other than
primary keys in 4.0.
He does, however, provide a possible workaround/hack (which comes with all the normal caveats):
As you are probably aware of, it is
often possible to “lie” to Entity
Framework and tell it in the SSDL, for
instance, that some unique key is the
primary key. I reckon this would work
very well if the actual primary key is
an surrogate key (i.e. an IDENTITY
column that was added for this
purpose) and you don’t even have to
map it in the model.