@jurisicmarko
March 2016
hibernate+envers
E. Evans, Domain Driven Design
<hibernate-mapping>
<class entity-name="Customer">
<id name="id"
type="long"
column="ID">
<generator class="sequence"/>
</id>
<property name="name"
column="NAME"
type="string"/>
<property name="address"
column="ADDRESS"
type="string"/>
<many-to-one name="organization"
column="ORGANIZATION_ID"
class="Organization"/>
<!-- ... -->
</class>
</hibernate-mapping>
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
@Target({FIELD, METHOD})
@Retention(RUNTIME)
public @interface MdiColumn {
String name() default "";
String type() default "string";
boolean id() default false;
}
@Target(TYPE)
@Retention(RUNTIME)
public @interface MdiEntity {
String name() default "";
String tableName();
}
@Entity
@Table(name = "BD_EVU")
@MdiEntity(tableName = "ADMIN_UIC")
public class Evu extends BaseEntity {
private static final int MIN_LENGTH = 2;
private static final int MAX_LENGTH = 4;
@Column
@NotNull
@Audited
@PdsField
@MdiColumn(id = true, name = "code")
private Long code;
@Transient
@JsonIgnore
private String description;
@Column
@Audited
@PdsField
@MdiColumn(name = "name")
private String name;
//getters and setters
}
@JsonIgnore
@MdiColumn(name = "privrail_admin_code")
public Long getPrivRailAdminCode() {
return privateRailRoute != null ? privateRailRoute.getAdminCode() : null;
}
private Configuration getConfiguration(Class modelClass) {
return new Configuration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.connection.url", "jdbc:h2:file:" + TEMP_DIR + H2_FILENAME + ";MV_STORE=FALSE;MVCC=FALSE")
.setProperty("hibernate.connection.driver_class", "org.h2.Driver")
.setProperty("hibernate.connection.username", "sa")
.setProperty("hibernate.connection.password", "")
.setProperty("hibernate.default_entity_mode", "dynamic-map")
.setProperty("hibernate.hbm2ddl.auto", "create")
.setProperty("hibernate.show_sql", "false")
.addXML(getHibernateMapping(modelClass));
}
private void saveEntities(Class modelClass, Session session, List activeEntities) {
final Map<String, Method> fieldMappings = getElementMappings(modelClass);
final String entityName = getEntityName(modelClass);
Transaction tx = session.beginTransaction();
activeEntities.forEach(object -> {
Map<Object, Object> entity = new HashMap<>();
fieldMappings.entrySet().forEach(entry -> {
try {
entity.put(entry.getKey(), entry.getValue().invoke(object));
} catch (IllegalAccessException | InvocationTargetException e) {
LOG.error("Error calling getter:" + entry.getValue().getName(), e);
}
});
session.save(entityName, entity);
exportReferences(session, object);
});
tx.commit();
}
private Map<String, Method> getElementMappings(Class modelClass) {
Map<String, Method> mappings = new HashMap<>();
// get regular fields and methods annotated with MdiColumn or MdiCompositeKey
Stream.concat(
getAnnotatedElements(modelClass, MdiColumn.class),
getAnnotatedElements(modelClass, MdiCompositeKey.class)).forEach(accessibleObject -> {
// stream only contains MdiColumn or MdiComposityKey ->
String columnName = accessibleObject.getAnnotation(MdiColumn.class) != null ?
accessibleObject.getAnnotation(MdiColumn.class).name() :
accessibleObject.getAnnotation(MdiCompositeKey.class).name();
if (StringUtils.isEmpty(columnName)) {
columnName = ((Member) accessibleObject).getName();
}
if (accessibleObject instanceof Field) {
try {
mappings.put(
columnName,
modelClass.getMethod("get" +
StringUtils.capitalize(((Field) accessibleObject).getName())));
} catch (NoSuchMethodException e) {
LOG.error("Getter method does not exist", e);
}
} else {
mappings.put(columnName, (Method) accessibleObject);
}
});
return mappings;
}
@Column
@NotNull
@Size(max = 100)
@Audited
@PdsField
@MdiColumn
private String name;
private Configuration getConfiguration(Class modelClass) {
return new Configuration()
//
.setProperty("hibernate.hbm2ddl.auto", "create")
//
}