Morphia: Saving document in a specific collection - java

I am using Morphia 2.x, and I have a usecase where i want to save 1 Entity class into 2 different Collections.
However Morphia 2.x save method doesn't have any option to pass a Collection Name, Where as Morphia 1.x had this option.
I am not sure why they have removed this option.
#Entity
public class Unit {
#Id
private String id;
protected Unit() {
}
public String getId() {
return this.id;
}
public void setId(final String id) {
this.id = id;
}
}

Morphia 2.3 will reintroduce this functionality as an option passed via the alternateCollection option on InsertOneOptions (among other options classes). I'm working to get this out soon.

Related

Morphia: Migrating existing data from Morphia 1.x to 2.x

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

org.hibernate.MappingException - What does this exception mean?

I'm getting the following error:
Could not determine type for: java.util.Set, at table: Ruleset, for columns: [org.hibernate.mapping.Column(ruleset)]
class snippet:
#Entity
public class Ruleset implements java.io.Serializable {
#Id
#OneToOne(targetEntity = RulesetStatus.class)
private Integer id;
private Set<Rule> ruleset = new HashSet<Rule>(0);
public Ruleset() {
}
public Ruleset(Integer ID, Set<Rule> ruleset) {
this.id = ID;
this.ruleset = ruleset;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Rule> getRuleSet(){
return this.ruleset;
}
public void setRuleset(Set<Rule> ruleset) {
this.ruleset = ruleset;
}
}
I've figured out that annotating ruleset as Transient makes the problem go away, but then ruleset won't be persisted to the DB. How do I tell hibernate about the type of this field?
I'm very new to Hibernate so I'm totally lost here.
__________________________Edit__________________________
The actual relationship should have been #ManyToMany as a rule can be in many rulesets and a ruleset can have many rules.
I added the #ManyToMany annotation to the set, then did not have a corresponding set in the Rule Class to map to. I added the set in the rule class, added the #ManyToMany annotation to that, and no I have no errors.
Does this seem correct?
By default, all fields (or properties) are mapped in JPA. That's why you have to tell the JPA provider what your Set is supposed to map (one-to-many, many-to-many, #ElementCollection, etc.), or map it as #Transient to tell the provider that you don't want the property to be persisted.

Generating UUID based #ID for Playframework 2.3x

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)

hibernate jpa entitymanager commit not writing objects to the database

I'm using hibernate JPA (without Spring) and it's working well, but I have come across a problem which has stumped me for the last 3 days.
I have written some generic DAO classes and am using them to persist my objects. They all work fine, except for one class of object which is not being persisted. No exceptions are thrown. I've tried debugging inside the hibernate code and found that the reason the entity is not being persisted is that in the org.hibernate.event.def.DefaultFlushListener onFlush() method, source.getPersistenceContext().getEntityEntries().size() == 0 so no flushing is performed. But I can't work out why that would be the case.
The classes in question look like this:
#Entity
#Table(name="er_batch_runs")
public class BatchRun implements Serializable, Comparable<BatchRun>, BatchBean {
private Long runId;
private String hostname;
.... more field here
#Override
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="runseq")
#SequenceGenerator(name="runseq", sequenceName="er_batch_runs_seq", allocationSize=1 /*, initialValue = 10*/)
#Column(name="batch_run_id")
public Long getId() {
return runId;
}
public void setId(long runId) {
this.runId = runId;
}
#Column(name="hostname")
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
pretty straightforward hibernate JPA stuff.
Here's another class:
#Entity
#Table(name="er_batch_txns")
public class BatchTxn implements Serializable, Comparable<BatchTxn>, BatchBean {
private long id;
.......... more fields
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="batchtxnseq")
#SequenceGenerator(name="batchtxnseq", sequenceName="ER_BATCH_TXNS_SEQ", allocationSize=1/*00, initialValue = 10*/)
#Override
#Id
#Column(name="BATCH_TXN_ID")
public Long getId() {
return id;
}
the BatchBean interface is what allows me to use generic DAOs like this:
public Long create(BatchBean newInstance) {
getOpenEntityManager().persist(newInstance);
logger.debug("hopefully created {} with id {}",newInstance.getTypeName(),newInstance.getId());
return newInstance.getId();
}
Transactions are being handled manually. I've set the flush type to COMMIT (ie flush on commit) and when I've completed the persist, I do a commit. After the persist, then BatchTxn object has been assigned a primary key from the sequence. When I debug hibernate I can see that getPersistenceContext().getEntityEntries() returns an empty Map.
so the question is why the BatchTxn is not being persisted by the commit, when the BatchRuns, and 5 other classes which implement BatchBean, are?
I'm using hibernate 3.6.0 Final
The only thing I saw that is suspected in your code is this in the BatchTxn class:
private long id;
This will be set automatically to zero. Maybe you should use Long (with a capital letter)?

GWT JPA - The response could not be deserialized

I use GWT and JPA for persistence. I have created a domain JPA enchanted classes, DAO's and RPC for communication between them. Everything works fine, through RPC the client sends the object to server but could not get response. Server cannot deserialize in a compatible way with the client side. So i cannot use the server callBack back to the client. The exception message is this:
The response could not be
deserialized,
com.google.gwt.user.client.rpc.SerializationException
Here's a sample code of one of my classes:
#Entity
#Table(name="course")
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
private int courseId;
private String name;
private List<Group> groups;
private List<Module> modules;
public Course() {
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(unique=true, nullable=false)
public int getCourseId() {
return this.courseId;
}
public void setCourseId(int courseId) {
this.courseId = courseId;
}
#Column(nullable=false, length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//bi-directional many-to-one association to Group
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
public List<Group> getGroups() {
return this.groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
//bi-directional many-to-one association to Module
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
public List<Module> getModules() {
return this.modules;
}
public void setModules(List<Module> modules) {
this.modules = modules;
}
}
If i remove the relationships it work's fine. This is done because collections like lists, set's e.t.c are converted into hibernate objects that cannot be handled by GWT client side.
Well the problem is that my class has #OneToMany association to another class. If i remove the association it work's fine. But it's impossible to that, since I use a normalized relational database
If you're using GWT-RPC, make sure that all of the classes you're trying to serialize have a public default (no-argument) constructor and implement Serializable. If you have embedded classes, they must also have a no-arg constructor.
Once , I have prepared gwt-jpa sample for this question. It is just serialization of JPA entity.. It might give you a clue about what is wrong in your case..
I used Gilead and it fixed the issue.
Please check the corresponding post: GWT with JPA
got it working...after a redeploy of war again...strange..cant point to one specific thing (as i did clear browser cache/eclipse classes output/restart eclipse)
Apparently workaround seems to be try redeploying webapp whenever this issue occurs..

Categories