Hibernate Annotations and Entity relations
@SecondaryTables
One to Many relationship
@Entity
public class Publisher {
private Long id;
@Id @GeneratedValue
public Long getId() { return id; }
}
@Entity
public class Book {
private Long id;
private Publisher publisher;
@Id @GeneratedValue
public Long getId() {return id;}
public Publisher getPublisher();
}
Publisher has many books, so publisher is in the ONE side while book in the MANY SIDE.
To have a unidirectional relation we can annotate the Book class as:
@ManyToOne public Publisher getPublisher();
or
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="publisher_id") // this will use publisher_id as attribute in the table, otherwise it will be publisher
public Publisher getPublisher();
Notice there is no need to have MappedBy as it is optional in the unidirectional ManyToOne relation.
with this approach, we can find the publisher from the Book, but finding books from an instance of Publisher object is not possible unless you use some queries. to be able to do that, we need to make the relationship bidirectional, just add this annotation in the Publisher side(ONE side):
@Entity
public class Publisher {
private Long id;
private List<Book> books;
@Id @GeneratedValue
public Long getId() { return id; }
@OneToMany
@OneToMany(mappedBy="publiser")
public List<Book> getBooks() { return books;}
}
It is mandatory to have mappedBy annotation in a bidirectional relationship and it has to be in the ONE side(maybe I’m wrong?), the ‘publisher’ here refer to the ‘publisher’ property in the MANY side. you can specify other attributes in the OneToMany annotation:
@OneToMany(cascade= CascadeType.ALL, mappedBy="publisher")
@OrderBy("Area desc")
Note: delete orphan to be added.
One to One relationship
@Entity
public class Door {
private Long id;
@Id
public Long getId() {return id;}
public void setId(Long id) { this.id = id;}
}
@Entity
public class Key {
private Long id;
@Id
public Long getId() { return id; }
public void setId(Long id) { this.id = id;}
}
their generated sql:
create table Door (
id bigint not null,
primary key (id)
);
create table Key (
id bigint not null,
primary key (id)
);
The only thing required to setup a one to one relationship is: to annotate in the one side of the relationship, let’s do it in the Door:
@Entity
public class Door {
private Long id;
private Key key;
@Id
public Long getId() { return id; }
public void setId(Long id) { this.id = id;}
@OneToOne
public Key getKey() { return key; }
public void setKey(Key key) { this.key = key;}
}
This change will trigger a change in the SQL as well:
create table Door (
id bigint not null,
key_id bigint,
primary key (id)
);
alter table Door
add index FK2097CE549DF154 (key_id),
add constraint FK2097CE549DF154
foreign key (key_id)
references Key (id);
Door owns the relationship in this case, and it is unidirectional, you can access Key from the Door, but not vice versa. to make it bi-directional you can annotate the other end:
@Entity
public class Key {
private Long id;
private Door door;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToOne
public Door getDoor() {
return door;
}
public void setDoor(Door door) {
this.door = door;
}
}
and you got the new sql:
create table Key (
id bigint not null,
door_id bigint,
primary key (id)
);
You will notice Key now has door_id as a foreign key, both end owns the relation, this isn’t too good. A preferable way is, one end is the owning entity while the other end is a owned entity, in example above we can make the Key a owned entity while Door is a owning entity, to make this happen, add a mappedBy in the Key class:
@OneToOne(mappedBy = "key")
the “key” field is referring to the key field in the Door class, this will generate a new SQL:
create table Key (
id bigint not null,
primary key (id)
);
We don’t have the door_id in this case as Key is only owned by Door, the relationship is maintained by Door with key_id as foreign key stored in the Door class. this allows us to travel from Key to Class as well.
If we want some operations cascaded from the owning class to the owned class, we can do:
@OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
public Key getKey() {
return key;
}
If you delete the Door, then the related Key object will be deleted as well. however this cascade operation does not happen when you do a batch delete on Door. If I understand correctly, the cascade and fetch type should always be specified in the owning entity side, thus it should be in the class that does not have a ‘mappedBy=’ clause, might not be correct. class with ‘mappedBy=’ annotation does not maintain the foreign key, it is in the other class.
Setting Up Exim4 in Ubuntu 8.10.x
Some related Links:
Setting up Exim SMTP Auth
SMTP Relaying Via a Smarthost
Gmail POP3 with Fetchmail
apt-get install mailx
apt-get install exim4
Note: this will remove the postfix if it is installed
To configure:
dpkg-reconfigure exim4-config
restart exim4:
invoke-rc.d exim4 restart
To relay with a smarthost, you need to update:
/etc/exim4/passwd.client, put something like this in the file:
example.com:abc@example.com:mypassword
restart the exim4 and do a test sending:
echo “my test” |mail -s “testing exim4″ abc@abc.com
check /var/log/exim4/mainlog and you should see some messages in the log about this test mail.
So far the exim was setup without smtp authorization, you need to enable SMTP Auth if you want to use RoundCube web mail in the same server.
Here is a guide about setting up the SMTP Auth.
Create a password for smtp and save it in /etc/exim4/passwd(create if not exists)
htpasswd -nd usernameforsmtp
copy and paste it to /etc/exim4/passwd (this has to be done when a new user is added, you do not have to restart exim4)
Update /etc/exim4/exim4.conf.template:
AUTH_SERVER_ALLOW_NOTLS_PASSWORDS=1
uncomment plain_server
sudo update-exim4.conf
restart exim4, this time the basic auth is on at least in the server side.
Really Setting up Apache Continuum in 10 min
The title is not misleading, everybody said it will take a few min to setup Apache Continuum, but I spent more than two days to have it up and running, looking back, I’d like to document steps of how to really set it up in 10 minutes.