Why does a class implements Serializable interface? [duplicate] - java

This question already has answers here:
When should we implement Serializable interface?
(3 answers)
Closed 6 years ago.
#Entity
public class Husband implements Serializable {
#Id
private int id;
private String name;
#OneToOne
private Wife wife;
}
#Entity
public class Wife implements Serializable {
#Id
private int id;
private String name;
#OneToOne(mappedBy="wife")
private Husband husband;
}
What is Serializable in broad term?
Why does a class implements Serializable interface?
Why does the husband member alone have #OnetoOne(mappedBy ="Wife"), but the wife member does not have #OnetoOne(mappedBy="husband")

Serialization, in broad terms, is the way Java provides developers to persist the state of any object to a persistent store.
If a developer wants that for some reason instance of his coded class should be persisted to a backing store, then the class needs to be declared as implementing Serializable.
The above code represents a One to One relationship between a Husband and a Wife. Which basically means that each wife is related to one husband and each husband is related to one wife. :-) Also in the above relationship, the Husband is the master of the relationship [in Entity-Relationship terms] and that is why Wife says that it is mapped/associated to Husband by the Husband and not the other way around. Which means Husband identifies its wife and not the other way around.

1) The Serializable interface is just a marker. It means that objects can be serialized, i.e. they can be represented as a bit string and restored from that bit string.
For example, both of your classes are serializable because they can be represented as a bit string (or regular string). On the other hand, a class that represents a file handle given out by the operating system can not be serialized: As soon as the program is finished, that handle is gone, and there is no way to get it back. Reopening the file by file name is not guaranteed to work, since it may have been deleted/moved/changed permissions in the meantime.
2) Serializing objects that don't implement the Serializable interface will result in a NotSerializableException being thrown.
3) According to the documentation:
mappedBy
This element is only specified on the inverse (non-owning) side of the association.

The interface Serializable helps to persist the state of an object instance.
According to the jpa specification:
"If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface" - JSR 220 Persistence - see 2.1 Requirements on the Entity Class
According to the java ee documentation:
"The field that owns the relationship. This element is only specified on the inverse (non-owning) side of the association." - Java EE 6 Documentation

I just want to answer the third question because it's not fully explained.
Here is your question:
Why does the husband member alone have #OnetoOne(mappedBy="Wife"), but the wife member does not have #OnetoOne(mappedBy="husband")
First, there is something wrong here: it should be:
#OneToOne(mappedBy="wife"), not Wife. Note that mappedBy should be followed by the attribute wife of the Husband class, not the class Wife, neither the Husband class name, although the Husband class is the owner. In the document of Hibernate is said:
mappedBy refers to the property name of the association on the owner side.
Second, one thing to have in mind is, there are two kinds of relationship when we do the database mapping: unidirectional and bidirectional. We use unidirectional relationship, when we only want one part handle/maintain this relationship, but from the other side, we are not interested in getting the data of this side. In your example, if we just want an unidirectional relationship from Husband to Wife class, we only want to know, by having an object of type Husband, who is his wife(by its getWife() method), but we are not interested in knowing one lady's husband.
Under this circumstance, we can code like this:
(note that in class Husband we have attribute of Wife type, but in Wife class we don't have attribute of Husband type)
Husband.java:
#Entity
public class Husband implements Serializable {
...
#OneToOne
//note that #JoinColumn is necessary when mapping,
//and although in the table you may have columns like
//`ID_WIFE` in table of Husband, in Java it's not a number
//attribute, it's an attribute of `Wife` type.
#JoinColumn(name="idWife")
private Wife wife;
}
Wife.java:
#Entity
public class Wife implements Serializable {
#Id
private int id;
private String name;
//We can omit the attribute `husband` of `Husband` type,
//because we are not interested in it. Or, we don't need
//to map in the owned side, because it's unidirectional.
}
But, if we want to have an bidirectional relationship, we have to map in both side and in the owned side, mappedBy is needed before the attribute owned.
We remain the Husband side intact, and we change the Wife.java:
Wife.java:
#Entity
public class Wife implements Serializable {
#Id
private int id;
private String name;
#OneToOne(fetch=FetchType.LAZY, mappedBy="wife")
private Husband husband;
}
Check this page: https://en.wikibooks.org/wiki/Java_Persistence/OneToOne, it explains it all in an understandable way.
Third, just a little note: the owner side, is commonly the class of a table with a FK of another table. Or, we just remember: the owner owns it all, so it also has the FK in its table.

Related

Schema design for inheritance strategy Table Per Class

I am trying to design a database schema so that it is applicable for the Hibernate's Table Per Class inheritance strategy. So, I will not let Hibernate to generate the tables, instead I need to design them myself in Liqibase but in such way that Hibernate can use them with that strategy.
My entity classes should look like this.
Vehicle.java
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
#Id #GeneratedValue
private int id;
private String name;
private String brand;
}
Car.java
#Entity
public class Car extends Vehicle {
private String oil;
}
Bike.java
#Entity
public class Bike extends Vehicle {
private String frame;
}
Now, I know that that this strategy means that all the fields are in all tables, but I am not sure about two things.
1) Do I need to include the ID in the derived tables?
2) Do I even need a Vehicle table in the DB, since it will actually never be used as an entity (rather just an abstract class)?
I'd appreciate if someone could clear that for me.
Now, I know that [the table-per-concrete-class] strategy means that all the fields are in
all tables,
Well no, you seem to be confused. With InheritanceType.TABLE_PER_CLASS, each concrete entity class E maps to a table that contains columns corresponding to all the fields of E, including inherited ones, but not including fields of entities that are not superclasses of E.
This is to be contrasted with InheritanceType.SINGLE_TABLE, in which all entity types in a whole inheritance hierarchy map to the same table, which then necessarily contains a column for each property of each entity in the hierarchy (without duplicating inherited fields).
Note also that it is odd that your Vehicle entity contains fields with the same names as fields of its subclasses. Java fields are not polymorphic, so this is unlikely to be what you want. It's certainly unnecessary.
but I am not sure about two things.
1) Do I need to include the ID in the derived tables?
Supposing that you stick with TABLE_PER_CLASS, yes, each entity table needs to provide a column for each persistent property of the corresponding entity class, including those inherited from superclasses. That includes id.
2) Do I even need a Vehicle table in the DB, since it will actually
never be used as an entity (rather just an abstract class)?
Not if you actually declare it abstract, but if you leave it concrete, then yes, you need a table for it. And that makes sense, because in that case you could have Vehicle entities that are neither Cars nor Bikes.
Hibernate schema generation tool should be able to generate your schema if you annotate your entities correctly.
In this case Vehicle table which be generated since your entity class is concrete. You need to define the class as abstract.
All the fields defined in the superclass (including the #Id) will be copied in the corresponding child class tables. There is a limitation though regarding id auto generation. You cannot use the table per class inheritance strategy with the GenerationType.IDENTITY strategy since the generated keys should be unique across all tables. Identity creates unique ids per table
Make sure the Generation.AUTO strategy does not map to the IDENTITY strategy for your RDBMS (You can specify a strategy explicitly eg GenerationType.TABLE to override the default)

what is difference between MappedSuperclass and Embeddable and how should be we used

A MappedSuperclass uses inheritance for field and code reuse.
In addition we leverage some composition via Embeddable feature provided Hibernate
#Embeddable
public class Department {
private long deptId;
private String name;
private String description;
}
#Entity
#Table(name="CSE_DEPT", schema="test")
public class CSEDepartment{
#Embedded
private Department dept;
}
What is difference between #MappedSuperclass and #Embeddable and what is appropriate situation where they use.
#MappedSuperClass is good when we want to share some state between different entities so they will have the same fields and you can reuse the fields in your different entities. Generally it is created as a abstract class and you cannot create its own instance. You use this when you want to mimic the 'Is A' relationship. It cannot be used as a target for associations.
#Embeddable is used to map composite value types. #Embeddable class is used as one of the field type with in our entities. you can use this when you want to mimic 'Has A' relationship.
The case you have stated in the question, it may not be suitable for any. because both MappedSuperClass and Embeddable cannot be an entity..(you have departmentid in the department class which i am assuming should be a primary key).
For your case better is to use #OneToOne entity association because cse department will have a uniqu id name and desc. you dont want to have 2 csedepartment in one college.

How to implement correctly an association in Java OOP code by a given class diagram?

I'm quite confused about how to implement correctly in java code, associations drawn on a UML class diagram.
Imagine we have just two classes (i.e. Order and Product) with association specified in different ways,
these associations could be drawn as following cases A,B or C:
Since I've found this answer: https://stackoverflow.com/a/2293760/3248096
that talks about (association with an arrow and navigability direction)
My first question is about difference on implementing B compared to A.
On A implementation I would write:
public class Order{
private Set<Product> products;
}
public class Product{
private Set<Order> orders;
}
On B implementation :
public class Order{
private Set<Product> products;
}
public class Product{
//no references properties back to order from here since no back navigability
...
}
Second question is about C model:
What's the best way (is there one?) to represent by implementation a limited cardinality from 0 to 4?
(Doesn't have much sense that a Product could have 0 to 4 parent orders. It's more about understanding modeling vs. code)
public class Product{
//Array(4) orders...?
}
An Order have several Product, so having a collection of Product into Order seems correct.
In the other hand, a instance of Product should be associated to only one Order. There are maybe a kind of ProductModel shared between several Product, but an instance of Product should be linked to only one Order for me. So, no more collection is needed here, no more link too because we have already a link between an order and these products.
So B implementation seems to be ok.
For second question, C implementation, you should have either an array with 4 slots or a collection with unlimited size. In both case, you must have to add code to control the state when adding or removing an element. For example, check if order has not already 4 products before accepting adding a new product, and handle the case properly.
About your question C.
Fixed-sized lists can be obtained this way:
public class Order {
private List<Product> products = Arrays.asList(new Product[4]);
}
See this link on ideone to see an example (please don't mind the public attribute, I'm just too lazy to write a setter method in this short example).
Code:
import java.util.*;
import java.lang.*;
import java.io.*;
class Product {
}
class Order{
public List<Product> products = Arrays.asList(new Product[4]);
}
/* Name of the class has to be "Main" only if the class is public. */
class Main
{
public static void main (String[] args) throws Exception
{
Order o = new Order();
o.products.set(0, new Product());
System.out.println(o.products);
o.products.add(new Product()); // throws UnsuportedOperationException
}
}
Okay, although asking multiple questions is not good style, here is an answer to A/B. Introducing navigability has only little semantics. It tells that you must be able to navigate in the direction of the arrow. So the originating class has a property of the class where the association points to. But in most cases from the design model it is obvious (from the methods implemented) which one needs a property for the other side. So you can leave it away with no issue at all.
Having said this, both implementations fulfill the design from the pure "arrow-context". The need for the private Set<Order> orders; arises from the overall system design. It would only be wrong if you left away private Set<Product> products; in the B-case.
Your model A does only specify a many-to-many association between Order and Product. It does not yet specify how this association is to be implemented with the help of reference properties: as a unidirectional or as a bidirectional association?
Your model B is probably intended to express a unidirectional many-to-many association between Order and Product realized in the form of a reference property Order::products. Notce, however, that this requires a different visual notation because UML navigability arrows do not have much semantics (they do not imply a reference property, but could also be taken care of by a query-based retrieval method of the associated products). You would have to replace the arrow head with an "association end ownership" dot, as explained in this post.
Your model C is just adding an upper multiplicity constraint, which would imply that you have to prevent users from making a fifth order of the same product. Using Java Bean annotations, this constraint could be expressed like so:
#Size(max=4) Set<Product> products;
You may want to read more about this in my book chapter on Associations.

using inheritence for data type purposes in JPA

I have some Entities that look like this:
#Entity
public abstract class AbstractEntity{
#Id
private Long id;
String name;
User author;
#Lob
byte[] data;
}
public class EntityOne extends AbstractEntity{
// nothing new
}
public class EntityTwo extends AbstractEntity{
// nothing new
}
public class EntityThree extends AbstractEntity{
// nothing new
}
The byte[] defined in the superclass is the interesting part of each subclass entity. The reason I want to subclass is to enforce typing rules, as some parts of the program require EntityThree, while some parts of the program require EntityTwo. the byte[] will have completely different meaning from subclass to subclass.
It feels a little strange, because I don't expect that any of the subclasses will add any fields or methods... So i use inheritance only as a typing tool.
Is this a reasonable design? A better way to accomplish this? Does it break any best practices?
It is a good OO practice. For the database, use the SINGLE_TABLE Inheritance strategy (the default), and maybe use a custom #DiscriminatorValue per subclass, otherwise you'll get classnames in your table.
From a DBA perspective, there is no difference between this and using a single class with a property TYPE.
For OO, the subclasses can be much more usefull, e.g. you can use it to implement certain methods differently or implement the visitor or strategy pattern instead of tedious if-then-else or instanceof structures.
It's hard to say without knowing the exact use-case, but it looks like you just want to reuse the common fields in all the entities, but that no other entity will have references to AbstractEntity - only to one specific subclass. In this case, you should map the superclass with #MappedSuperclass rather than with #Entity. Each entity will have its own table, and can override the mapping defined in the mapped superclass.
Note that if I'm mistaken, and you really need an entity inheritance, using instanceof, at least with Hibernate, will cause problems, because you might have a proxy to the base class, which doesn't know yet the exact subclass the foreign key is pointing to, and which is thus not an instance of any of the subclasses.

bidirectional one-to-one relationship (mappedBy)

You create a bidirectional one-to-one relationship using fields on
both classes, with an annotation on the child class's field to declare
that the fields represent a bidirectional relationship. The field of
the child class must have a #Persistent annotation with the argument
mappedBy = "...", where the value is the name of the field on the
parent class. If the field on one object is populated, then the
corresponding reference field on the other object is populated
automatically.
What can a bidirectional one-to-one relationship do?
Can someone give me a example?
And why I always got this error.
Class "com.example.datastore.Employee" has field "contactInfo" with
"mapped-by" specified as "contactInfo". This field doesnt exist in the
target of the relation ("com.example.datastore.ContactInfo")!!
Thanks in advance!
I try to answer from what I learnt from Hibernate/JPA (which I think is similar)
Seems that your ContactInfo do not have relationship to Employee. To use what you described as an example for bidirectional one-to-one relationship, you will see something like (it is probably not syntactically correct, just to give u idea):
public class Employee {
//... other relationship or fields
#OneToOne(mappedBy="employee") // the field in ContactInfo
private ContactInfo contactInfo;
}
public class ContactInfo {
#OneToOne
#JoinColumn("EMP")
private Employee employee;
}
The 'real' relationship in persistence layer is in fact dominated by ContactInfo.employee. Setting Employee.contactInfo will not cause persistence layer to contain correct data.
I wish this help and applies to JDO too. :P
It sounds like you have a one-to-one of Employee to ContactInfo. An employee has exactly one contact info, and a contact info belongs to exactly one employee. That's a bidirectional one-to-one. Your error is occurring because "mapped-by" needs to specify the name of the property of the other object that refers back to this one. For example, if you have
class Employee {
private ContactInfo contactInfo;
}
class ContactInfo {
private Employee employee;
}
then when you map the Employee.contactInfo property, its "mapped-by" would be "employee" because that's the property that it's "mapped by" in the ContactInfo.
First the Error What the error is saying is that contactInfo is not a field of class com.example.datastore.ContactInfo . They field mapped by must be a field\property of the class you are mapping to .
Second The concept of Bi-Direction Mapping
It's just that two tables in one-to-one or one-to-many relationship where both entities will have knowledge of the other s. You do not always need it and that depends on situation and context but generally is more common to have bi-directional one to many than one to one.
You question is about one-to-one so to give you an example of when both entities need to know about each other from Hibernate docs A bidirectional one-to-one association on a join table is possible, but extremely unusual. But if you really wanted to be able to get either entiy from which ever table (which is very rare) then you create bi-directional one to one
Person and Address just to quote an example

Categories