If I remember the documentation correctly, accessing a property that
hasn't been loaded
before will load the whole object. So basically just accessing one of
the lazy loaded properties
prior to serialization/cloning/whatever should do the trick.
Afaik, this does not apply to stuff annotated with @Lob, so you'd have
to manually access that
before serialization.
On Friday, 27 April 2012 07:51:42 UTC-4, Dominik Dorn wrote:If I remember the documentation correctly, accessing a property that
hasn't been loaded
before will load the whole object.
Yeah, this works (and is what I've been doing), but I was hoping for a more elegant solution- I'm trying to create a method in a base class that creates the copy.
I can't tell which property hasn't been lazy loaded yet, so I have to access all of them.
>> If I were to submit a patch to make the Vanilla Serialization do this, would it be accepted
There would be a few issues that need addressing.
- How does it work in terms of object graph depth
An Object having lazy loading done at the "Include" level would cause the "Exclude" level to be used for nested properties.
I'm not sure how easy this would be easy to fit seamlessly into the java serialization model because it might be hard to tell if something is the "root" object - it might be possible to use a transient field to pass down the information during the serialization process.
If it ends up being impractical to integrate with the java serialization process, it seems like it'd be at least possible to have something like a Ebean.toVanillaObject(Object) method that could do this.
- Does it maintain the current behavior for all the existing users
As a 'left field' thought ... have you considered other options like JSON, XML etc.
That is, when you serialise an ORM object graph you will often pull in a lot of relationships and serialise a lot more than you need / desire. Serializing Order ... Order + Order Details + Product + Customer + Customer Contacts
...
If you serialize using JSON say then you can choose exactly what parts of the object graph are included.
If we want to have that sort of control with Object serialisation then we'd also need to replace referred beans with 'reference beans' ... so before you serialize a order bean the customer bean is actually replaced with a reference bean (so that a full customer bean doesn't get serialised effectively cascading to all its related beans etc).
Hmmm.
>> I wanted to make a copy of an Object
It would be good to understand the purpose of the copy. Typically I'd expect people to use serialization to transport the object graph or persist it to a file system.
What we don't want is the default behavior to be ... 'serialize an order bean and half the database gets lazy loaded'.
My interpretation is that for this functionality you'd like to have a 'shallow copy' function that also ensures that the bean is fully loaded.
So its a 'shallow' copy meaning that any @ManyToOne and @OneToOne objects get replaced by reference beans (so not a cascading copy function).
Does that sound about right?
>> I wanted to make a copy of an Object
It would be good to understand the purpose of the copy. Typically I'd expect people to use serialization to transport the object graph or persist it to a file system.
@Entity
@Table(name = "region")
public class Region extends BaseModel {
private static final long serialVersionUID = 1569807861428929099L;
public static Finder<Long, Region> find = new Finder<Long, Region>(
Long.class, Region.class);
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Long id;
@Basic(optional = false)
@Column(name = "name", nullable = false, length = 255)
private String name;
@OneToMany(mappedBy = "region")
private List<DriverRegion> regions;
public static String getRegionJson(Region region) {
Map<String, Region> map = Ebean.find(Region.class)
.where()
.eq("region", region)
.findMap("id", String.class);
JsonContext jsonContext = Ebean.createJsonContext();
JsonWriteOptions jsonWriteOptions = JsonWriteOptions
.parsePath("(name)");
String ret = jsonContext.toJsonString(map, true, jsonWriteOptions);
return ret;
}
Inside DriverRegion.java:
@Entity
@Table(name = "driver_region", uniqueConstraints = @UniqueConstraint(columnNames = {
"driver_id", "region_id" }))
public class DriverRegion extends Model {
private static final long serialVersionUID = 3233477537300849362L;
public static Finder<Long, DriverRegion> find = new Finder<Long, DriverRegion>(
Long.class, DriverRegion.class);
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Long id;
@ManyToOne
@JoinColumn(name = "driver_id")
private Driver driver;
@ManyToOne
@JoinColumn(name = "region_id")
private Region region;
@Column(name = "is_active")
private boolean isActive;
...
}
Inside Driver.java:
@Entity
@Table(name = "driver", uniqueConstraints = @UniqueConstraint(columnNames = {
"username" }))
@XmlRootElement
public class Driver extends BaseModel {
private static final long serialVersionUID = -2378727866829160641L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@OneToMany(mappedBy = "driver")
private List<DriverRegion> regions;
...
}
{"id":4,"firstName":"Jack","lastName":"Black","phone":null,"mobile":null,"email":"blac...@test.com",
"group":null,"cretime":"2012-05-04T12:03:10.714Z","updtime":"2012-05-04T12:03:10.714Z"}
]},
"3":
{"id":3,"status":"ACTIVE","name":"Fiona",
"shippingAddress":{"id":4,"line1":"12 Apple St","city":"Auckland"},
"billingAddress":{"id":3,"line1":"West Coast Rd","line2":"St Lukes","city":"Auckland","cretime":null,
"country":{"code":"NZ"},"updtime":"2012-05-04T12:03:10.714Z"},
"contacts":[
{"id":5,"firstName":"Jim1","lastName":"Cricket","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.715Z","updtime":"2012-05-04T12:03:10.715Z"},
{"id":6,"firstName":"Fred1","lastName":"Blue","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.716Z","updtime":"2012-05-04T12:03:10.716Z"},
{"id":7,"firstName":"Bugs1","lastName":"Bunny","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.716Z","updtime":"2012-05-04T12:03:10.716Z"},
{"id":8,"firstName":"Fiona","lastName":"Black","phone":null,"mobile":null,"email":"blac...@test.com",
--
---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
public static String getRegionJson(Region region) {
Map<String, Region> map = Ebean.find(Region.class)
.select("name")
.fetch("regions")
.where()
.eq("region", region)
.findMap("id", String.class);
JsonContext jsonContext = Ebean.createJsonContext();
JsonWriteOptions jsonWriteOptions = JsonWriteOptions
.parsePath("(uuid,name)");
String ret = jsonContext.toJsonString(map, true, jsonWriteOptions);
return ret;
}
{"id":4,"firstName":"Jack","lastName":"Black","phone":null,"mobile":null,"email":"black1@test.com",
"group":null,"cretime":"2012-05-04T12:03:10.714Z","updtime":"2012-05-04T12:03:10.714Z"}
]},
"3":
{"id":3,"status":"ACTIVE","name":"Fiona",
"shippingAddress":{"id":4,"line1":"12 Apple St","city":"Auckland"},
"billingAddress":{"id":3,"line1":"West Coast Rd","line2":"St Lukes","city":"Auckland","cretime":null,
"country":{"code":"NZ"},"updtime":"2012-05-04T12:03:10.714Z"},
"contacts":[
{"id":5,"firstName":"Jim1","lastName":"Cricket","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.715Z","updtime":"2012-05-04T12:03:10.715Z"},
{"id":6,"firstName":"Fred1","lastName":"Blue","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.716Z","updtime":"2012-05-04T12:03:10.716Z"},
{"id":7,"firstName":"Bugs1","lastName":"Bunny","phone":null,"mobile":null,"email":null,
"group":null,"cretime":"2012-05-04T12:03:10.716Z","updtime":"2012-05-04T12:03:10.716Z"},
{"id":8,"firstName":"Fiona","lastName":"Black","phone":null,"mobile":null,"email":"black2@test.com",