You can model the association as a separate Association entity. The temporal data can be modelled as regular Date attributes (as @Temporal(TemporalType.TIMESTAMP)).
You can model the PK of an association as the composition of the foreign keys of Entity_1 and Entity_2 - this would make the association a dependent entity. Or you can assign it an own id and connect to Entity_1 and Entity_2 via ManyToOne relationships.
EDIT: The bulk of my example implementation is shamelessly stolen from @Vlad's answer, since the main difference is that an entity has an id and is queryable while an embeddable is not.
I have removed @Column(updatable=false) from the Date columns, because I am not sure that this is required and added @Temporal(TemporalType.TIMESTAMP) because it is required by the JPA spec and thus increases portability.
Since this is a bidirectional mapping, I use mappedBy on the inverse side (the entities) instead of JoinColumn on the owning side (the association).
@Entity
public class Association {
@Id
@GeneratedValue(...)
private Long id;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date affectation;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date expiration;
@ManyToOne(fetch=FetchType.LAZY)
private Entity1 entity1;
@ManyToOne(fetch=FetchType.LAZY)
private Entity2 entity2;
}
Entity1 and Entity2 look the same, just replace the digit. I am not sure about the added value of using the Set interface, so I replaced it with List, but perhaps I am missing something.
public class Entity1 {
@OneToMany(mappedBy="entity1")
private List<Association> associations = new ArrayList<Association>();
...
}