This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
In a class made by "entity class from database" there is @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "ID", nullable = false) private Integer id; The following methods are also generated. But seems they are invalid for an auto generated field. It would be an error for an application to use them. public Person(Integer id) { this.id = id; } public void setId(Integer id) { this.id = id; }
Is there any realm error if I'll use these methods?
em.getTransaction().begin(); p1.setId(1000000); em.getTransaction().commit(); results in Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934): org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the database. Updates are not allowed. javax.persistence.RollbackException: Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934): org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the database. Updates are not allowed. at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102) at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63) at org.metawb.astro.db.PersonTest.setUp(PersonTest.java:61) Caused by: Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934): org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the database. Updates are not allowed. at org.eclipse.persistence.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2372) ...... and clearDb(); assert em == null; getEm(); em.getTransaction().begin(); p1 = new Person(1000000); em.persist(p1); em.getTransaction().commit(); em.getTransaction().begin(); p1.setFirstName("Ernie"); em.getTransaction().commit(); relEm(); gives surprising results, notice that the "p1.setFirstName("Ernie");" is lost somewhere. In some ways it seems an exception should be thrown. ij> select * from person; ID |LAST_NAME |FIRST_NAME |MIDDLE_NAME ----------------------------------------------- 21 |NULL |NULL |NULL 1 row selected Finally, using the correct constructor p1 = new Person(); in the previous example gives the expected results ij> select * from person; ID |LAST_NAME |FIRST_NAME |MIDDLE_NAME ------------------------------------------------ 22 |NULL |Ernie |NULL 1 row selected I would guess that there are cases where they could be used with em.merge if you knew the id. But these seem rare and specialized cases that shouldn't be in the default classes (my opinion).
"Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934): org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the database. Updates are not allowed." it's look like an issue with attempt to update primary key and not the issue with autogenerated key. As for second sample with missed name it may be eclipselink/database issue or need additional investigation. Is there any real restrictions from database side to specify id for new row instead of autogenerate?
I understand why it is behaving this way, I believe the run-time behavior is correct. The idea of this issue: the created methods and constructors that allow the programmer to attempt to set the "ID" are invalid. They should not be auto created by the "entity from database" action because if they are used then errors or unexpected things happen. For this table in derby, the sql create is CREATE TABLE ernie.person ( id INT NOT NULL GENERATED ALWAYS AS IDENTITY , last_name VARCHAR(45) , first_name VARCHAR(45) , middle_name VARCHAR(45) , PRIMARY KEY (id) ) ; I am assuming there is enough info in the db schema to know that the column can not be written, that is is only autogen (but I don't know for sure).
"if they are used then errors or unexpected things happen." it may be only in case of inappropriate usage, otehrwise we can say no methods should be generated for fields with "not null" constraint, as user can try to call setId(null) and persist (and it will cause error) in case if it's not autogenerated field etc.
may be I need to try some use-cases first (with usage of constructor and setter in case of autogenerated pk)
for example I can create create table greetings (i int generated by default as identity, ch char(50)); and PK will be autogenerated and derby will allow to specify pk anyway.
> generated by default as identity > derby will allow specify pk Yes, that is true. But in my example, I have > GENERATED ALWAYS AS IDENTITY and you can *not* specify pk If there is a standard way to determine that difference from the schema (or however the action works) then it seems the second case should not have the methods/constructors that allow the pk to be set. I don't think this is a serious problem, it is just that the class has confusing and misleading methods. Consider CREATE TABLE ernie.eventType ( id INT NOT NULL GENERATED ALWAYS AS IDENTITY , name VARCHAR(45) NOT NULL , PRIMARY KEY (id) ) The only generated constructor to set the name is public Eventtype(Integer id, String name) { this.id = id; this.name = name; } but this is misleading, what I really want public Eventtype(String name) { this.name = name; }
yes, looks reasonable to generate Eventtype(String name), but also should be not problem with call 'new Eventtype(null, name)'. as it's not serious problem and mostly usability issue, it may more like enhancement request for better support for 'GENERATED ALWAYS AS IDENTITY' keys.
I don't see appropriate api in org.netbeans.modules.dbschema.ColumnElement, pass for evaluation. feel free to pass back and file separate issue if it will be more appropriate.
I mean api to get if it's ALWAYS or DEFAULT auto-increment.
*** Bug 177448 has been marked as a duplicate of this bug. ***
Removed 154413 - persistence generation still uses dbschema ... I'm inclined to close this as won't fix. Reasoning: DBs have a different approaches to generated keys - I checked: - Derby: integer GENERATED ALWAYS AS IDENTITY => not insertable, not updateable - Informix: serial => insertable, not updateable - MySQL: integer primary key auto_increment => insertable, updateable So what would be appropriate? I see three possible approaches: Check based on DBMS - this does not scale (the jdbc driver does expose generated column, but whether that is reliable I would doubt it). While this would be correctly done in the dbschema/db.metadata modules. I would argue, that this defeates the purpose of JPA. Always generate the setter to support DBs allowing INSERT/UPDATE. Drawback: You violate DBs that don't support parts of the set. Don't generate setters. Drawback: You take away the option to set the IDs were possible. My take: Its the responsibility of the developer to use/not use the feature, that the entity provides. The developer always has to be careful when setting IDs - he could check the underlying DB at runtime or add appropriate error handling.
Ok - I gave it another thought and won't fix this. The argument in comment 13 stands and reading the docs for oracle db 12c both cases (update+not updateable) are appliable to oracle.