Good day Guys,
I want to create Models that don't use the default #Id auto generation for Playframework and Ebeans. I have seen online that there are options for Using GenericModel, however that class doesn't seem to be included in version 2.3x. I have done this in order to workaround it but i still fall short my aim
public class ProductVariants extends Model
{
#Id
String id;
public String getId() {
return (this.id == null) ? UUID.randomUUID().toString() : this.id;
}
public void setId(String id) {
this.id = id;
}
}
The issue with this is that i have to manually set the ID before i can save the object e.g.
productVariant.setId(productVariant.getId());
productVariant.save();
Both for a primary model and all it related models with a OneToMany relationship, and it is currently giving me issues when i bind from the view to the Model object with error ERROR executing DML bindLog[] error[Field 'id' doesn't have a default value]]].
Please any help will be appreciated.
Good day Guys,
I finally fixed this by using the UUID class that ships with the JDK. So when you are creating your Models you create them with the
#Id
public java.util.UUID id
Also in the routes file if you need to map to a record by the ID you can do that by doing something like this
GET /:pid/edit controllers.Application.edit(pid: java.util.UUID)
Related
I am trying to update the Morphia version from 1.x to 2.x.
While doing that i have noticed that now the discriminator in the database is also changed.
previously it was className="app.package.className" and now it is changed to _t="className".
I found that we can explicitly mention the discriminatorKey and discriminator in the #Entity annotation as a parameter.
But still I am not very sure how can i migrate existing data to support the new discriminator in version 2.x.
#Entity(discriminatorKey="className", discriminator="Unit")
public class Unit {
#Id
private String id;
protected Unit() {
}
public String getId() {
return this.id;
}
public void setId(final String id) {
this.id = id;
}
}
Recently I had encountered a same situation. You can create two different Datastore of the new morphia package. The first one with legacy MapperOptions and the second with the new default MapperOptions.
Datastore datastoreLegacy = Morphia.createDatastore("dbName", MapperOptions.legacy().build());
Datastore datastoreNew = Morphia.createDatastore("dbName");
Then you can use the legacy datastore to query documents from your Unit collection and store them with the new datastore. This example shows how to perform it on every document in two statements. If the collection has a lot of data, then you should probably iterate over all documents.
List<Unit> units = datastoreLegacy.find(Unit.class).stream().collect(Collectors.toList());
datastoreNew.save(units);
I have to manage a Datatransfer between 2 DBs (mssql) with hibernate.
When i load an object from one DB with session.get() it already has a private key. Then i need to persist it to the other DB with anotherSession.replicate(Object o).
My Problem ist, that the given PK is not persisted but replaced by another one.
PS: Both the srcTable and the destTable have PK generation Identity and it needs to stay that way.
If you map an Entity ID with generation "identity", Hibernate will always generate a new ID as soon as you try to persist it. You will have to switch the generation to "assigned" to keep your old ID.
If you have something like it
#Entity
public class Project {
#Id #GeneratedValue long id; // still set automatically
}
You have to remove the #GeneratedValue annotation from id field. Else jpa will generate a value for id before insertion.
#Entity
public class Project {
#Id long id; // must be initialized by the application
:
}
Solution To Your Problem
Create a an entity containing all the mapping definition.
Create a ID field in your new class without the #Generated value annotation.
Clone the old entity to this new one.
Persist this new entity.
Now if you create a subclass extending your entity then the whole
process becomes very easy.
Sample Code For This Solution
Existing Entity
#Entity
#Table(name="EJB_PROJECT")
public class OldEntity implements Serializable {
#Id
#Column(name="PROJECT_ID", primaryKey=true)
#GeneratedValue
Integer id;
}
New Entity
#Entity
#Inheritance(strategy=SINGLE_TABLE)
#Table(name="EJB_PROJECT")
public class NewEntity extends OldEntity {
#Id
#Column(name="PROJECT_ID", primaryKey=true)
Integer id;
// Constructor to clone old entity's id
public NewEnity(OldEntity old) {
this.id = old.id;
}
}
Persisting code
em.persist(new NewEntity(oldEntity));
We using MYSQL and Hibernate for our project.
JPA is used to persist object in DB.
We have Multiple class with similar code
#Entity
#Table(name = "users")
class Users implement Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
.
.
.
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Now we want to give support for oracle too. How should we do it ?
strategy=GenerationType.AUTO is not supported by oracle.
One soln is we can define sequence in each POJO which we do not want to do?
please provide us some input so that we can move ahead.
The AUTO strategy should work on Oracle as well. The difference with MySQL is that it will use a sequence instead of relying on an auto_increment ID.
You can even control the sequence name per entity if desired: see Hibernate sequence on oracle, #GeneratedValue(strategy = GenerationType.AUTO).
#Id
#SequenceGenerator(name="admin_seq", sequenceName="unique_id")
#GeneratedValue(strategy=GenerationType.AUTO, generator="admin_seq")
private Long id
worked for me , thanks for all your answers
How to set id in model? I try this code:
public Community(Long id, ...) {
this.id = id;
....
}
But when I do this:
Communtiy c = new (1, ...);
c.save();
Hibernate say:
Execution exception PersistenceException occured : org.hibernate.PersistentObjectException: detached entity passed to persist: models.Community
You can do this by extending from play.db.jpa.GenericModel instead of play.db.jpa.Model. This will allow you to set the primary key manually.
In fact, what Model does is extend from GenericModel and because it is very common to do so Model automatically generates primary keys ( by using #Id #GeneratedValue public Long id ). But if for whatever reason you want to set a custom primary key, then extending from GenericModel is the way to go.
Official documentation here.
Example
#Entity
public class Community extends GenericModel {
#Id
public Long id;
public Community (Long id) {
this.id = id;
}
}
Try not set id on your own, id should be loaded to model after save.
I have a post class and it kind of works, but there's one problem: the primary key doesn't increase.
#Entity
#Table(name="posts")
public class Post extends GenericModel{
#Id
#Column(name="post_id")
public int id;
#Column(name="post_situation")
public String situation;
#Column(name="post_date")
public Date date;
#Column(name="post_userid")
public int userid;
#OneToMany(mappedBy="post", cascade=CascadeType.ALL)
public List<Block> blocks;
public Post addBlock(String content, int position){
Block b = new Block(this, content, position);
b.save();
this.blocks.add(b);
this.save();
return this;
}
public Post(String situation, Date date){
this.situation = situation;
this.date = date;
this.userid = 2;
}
}
When I call it the first time on an empty table, it works fine, but the second time, I'm getting PersistenceException occured : org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
The post_id column always has 0. Any idea how to fix this? I have the #Id annotation in palce..
This is how I have in my controller:
Post p = new Post("Midden in het middenoosten.", new Date()).save();
Any ideas what's causing this problem?
It seems that you want the primary key values to be auto-generated. If that is the case, if you'll need to add the #GeneratedValue annotation to the id attribute, in addition to the #Id annotation. Your code should therefore be:
#Id
#Column(name="post_id")
#GeneratedValue
public int id;
There are several strategies available to generate the Ids. You would have to read up on those to decide if you want to choose the TABLE -based, SEQUENCE -based or the IDENTITY -based strategy (which depends on what your database supports). If you choose a strategy explicitly, the define strategy will be used, instead of the default AUTO strategy. Explicit strategy decisions, are communicated in code as:
#Id
#Column(name="post_id")
#GeneratedValue(strategy=SEQUENCE, generator="POST_SEQ")
public int id;
Without generated values, the default value for integers in Java, i.e. 0 will be persisted for the post_id column. Due to the primary key constraint, you cannot have a second row with the same key, resulting in the described failure.
There are several strategies available to generate id:
GenerationType.AUTO
GenerationType.SEQUENCE
GenerationType.IDENTITY
GenerationType.TABLE
If you want the primary key values to be auto-generated, use GenerationType.AUTO, it works with MySQL.