HHH-7690 - @EmbeddedId with @ManyToOne inside

This commit is contained in:
Lukasz Antoniak 2012-10-25 12:56:27 +02:00
parent 61eaf4ce4e
commit ac511bf72e
8 changed files with 408 additions and 8 deletions

View File

@ -90,11 +90,12 @@ public final class BasicMetadataGenerator {
} }
@SuppressWarnings({"unchecked"}) @SuppressWarnings({"unchecked"})
boolean addKeyManyToOne(Element parent, PropertyAuditingData propertyAuditingData, Value value, boolean addManyToOne(Element parent, PropertyAuditingData propertyAuditingData, Value value,
SimpleMapperBuilder mapper) { SimpleMapperBuilder mapper) {
Type type = value.getType(); Type type = value.getType();
Element manyToOneElement = parent.addElement("key-many-to-one"); // A null mapper occurs when adding to composite-id element
Element manyToOneElement = parent.addElement(mapper != null ? "many-to-one" : "key-many-to-one");
manyToOneElement.addAttribute("name", propertyAuditingData.getName()); manyToOneElement.addAttribute("name", propertyAuditingData.getName());
manyToOneElement.addAttribute("class", type.getName()); manyToOneElement.addAttribute("class", type.getName());
MetadataTools.addColumns(manyToOneElement, value.getColumnIterator()); MetadataTools.addColumns(manyToOneElement, value.getColumnIterator());

View File

@ -64,7 +64,7 @@ public final class IdMetadataGenerator {
if (!"_identifierMapper".equals(property.getName())) { if (!"_identifierMapper".equals(property.getName())) {
boolean added = false; boolean added = false;
if (propertyType instanceof ManyToOneType) { if (propertyType instanceof ManyToOneType) {
added = mainGenerator.getBasicMetadataGenerator().addKeyManyToOne(parent, added = mainGenerator.getBasicMetadataGenerator().addManyToOne(parent,
getIdPersistentPropertyAuditingData(property), getIdPersistentPropertyAuditingData(property),
property.getValue(), mapper); property.getValue(), mapper);
} else { } else {

View File

@ -256,7 +256,7 @@ public class MetadataTools {
while (properties.hasNext()) { while (properties.hasNext()) {
Element property = properties.next(); Element property = properties.next();
if ("property".equals(property.getName())) { if ("property".equals(property.getName()) || "many-to-one".equals(property.getName())) {
Attribute nameAttr = property.attribute("name"); Attribute nameAttr = property.attribute("name");
if (nameAttr != null) { if (nameAttr != null) {
nameAttr.setText(prefix + nameAttr.getText()); nameAttr.setText(prefix + nameAttr.getText());
@ -265,14 +265,16 @@ public class MetadataTools {
changeNamesInColumnElement(property, columnNameIterator); changeNamesInColumnElement(property, columnNameIterator);
if (changeToKey) { if (changeToKey) {
property.setName("key-property"); property.setName("key-" + property.getName());
} }
if ("property".equals(property.getName())) {
Attribute insert = property.attribute("insert"); Attribute insert = property.attribute("insert");
insert.setText(Boolean.toString(insertable)); insert.setText(Boolean.toString(insertable));
} }
} }
} }
}
/** /**
* Adds <code>formula</code> element. * Adds <code>formula</code> element.

View File

@ -0,0 +1,68 @@
package org.hibernate.envers.test.integration.ids.embeddedid;
import org.hibernate.envers.Audited;
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class Item implements Serializable {
@EmbeddedId
private ItemId id;
private Double price;
public Item() {
}
public Item(ItemId id, Double price) {
this.id = id;
this.price = price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Item)) return false;
Item item = (Item) o;
if (getId() != null ? !getId().equals(item.getId()) : item.getId() != null) return false;
if (getPrice() != null ? !getPrice().equals(item.getPrice()) : item.getPrice() != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (price != null ? price.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Item(id = " + id + ", price = + " + price + ")";
}
public ItemId getId() {
return id;
}
public void setId(ItemId id) {
this.id = id;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}

View File

@ -0,0 +1,83 @@
package org.hibernate.envers.test.integration.ids.embeddedid;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Embeddable
public class ItemId implements Serializable {
@Column(name = "model")
private String model;
@Column(name = "version")
private Integer version;
@ManyToOne
@JoinColumn(name = "producer")
private Producer producer;
public ItemId() {
}
public ItemId(String model, Integer version, Producer producer) {
this.model = model;
this.version = version;
this.producer = producer;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ItemId)) return false;
ItemId itemId = (ItemId) o;
if (getModel() != null ? !getModel().equals(itemId.getModel()) : itemId.getModel() != null) return false;
if (getProducer() != null ? !getProducer().equals(itemId.getProducer()) : itemId.getProducer() != null) return false;
if (getVersion() != null ? !getVersion().equals(itemId.getVersion()) : itemId.getVersion() != null) return false;
return true;
}
@Override
public int hashCode() {
int result = model != null ? model.hashCode() : 0;
result = 31 * result + (version != null ? version.hashCode() : 0);
result = 31 * result + (producer != null ? producer.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "ItemId(model = " + model + ", version = " + version + ", producer = " + producer + ")";
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Producer getProducer() {
return producer;
}
public void setProducer(Producer producer) {
this.producer = producer;
}
}

View File

@ -0,0 +1,71 @@
package org.hibernate.envers.test.integration.ids.embeddedid;
import org.hibernate.envers.Audited;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class Producer implements Serializable {
@Id
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
public Producer() {
}
public Producer(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Producer)) return false;
Producer producer = (Producer) o;
if (getId() != null ? !getId().equals(producer.getId()) : producer.getId() != null) return false;
if (getName() != null ? !getName().equals(producer.getName()) : producer.getName() != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Producer(id = " + id + ", name = " + name + ")";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,92 @@
package org.hibernate.envers.test.integration.ids.embeddedid;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@Entity
@Audited
public class PurchaseOrder implements Serializable {
@Id
@GeneratedValue
private Integer id;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "model", referencedColumnName = "model", nullable = true),
@JoinColumn(name = "version", referencedColumnName = "version", nullable = true),
@JoinColumn(name = "producer", referencedColumnName = "producer", nullable = true)})
private Item item;
@Column(name = "NOTE")
private String comment;
public PurchaseOrder() {
}
public PurchaseOrder(Item item, String comment) {
this.item = item;
this.comment = comment;
}
public PurchaseOrder(Integer id, Item item, String comment) {
this.id = id;
this.item = item;
this.comment = comment;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PurchaseOrder)) return false;
PurchaseOrder that = (PurchaseOrder) o;
if (getComment() != null ? !getComment().equals(that.getComment()) : that.getComment() != null) return false;
if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
if (getItem() != null ? !getItem().equals(that.getItem()) : that.getItem() != null) return false;
return true;
}
@Override
public String toString() {
return "PurchaseOrder(id = " + id + ", item = " + item + ", comment = " + comment + ")";
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (item != null ? item.hashCode() : 0);
result = 31 * result + (comment != null ? comment.hashCode() : 0);
return result;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}

View File

@ -0,0 +1,83 @@
package org.hibernate.envers.test.integration.ids.embeddedid;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.Arrays;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue(jiraKey = "HHH-7690")
public class RelationInsideEmbeddableTest extends BaseEnversJPAFunctionalTestCase {
private Integer orderId = null;
private ItemId itemId = null;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[]{PurchaseOrder.class, Item.class, ItemId.class, Producer.class};
}
@Test
@Priority(10)
public void initData() {
EntityManager em = getEntityManager();
// Revision 1
em.getTransaction().begin();
Producer producer = new Producer(1, "Sony");
ItemId sonyId = new ItemId("TV", 1, producer);
Item item = new Item(sonyId, 100.50);
PurchaseOrder order = new PurchaseOrder(item, null);
em.persist(producer);
em.persist(item);
em.persist(order);
em.getTransaction().commit();
// Revision 2
em.getTransaction().begin();
order = em.find(PurchaseOrder.class, order.getId());
order.setComment("fragile");
order = em.merge(order);
em.getTransaction().commit();
// Revision 3
em.getTransaction().begin();
item = em.find(Item.class, sonyId);
item.setPrice(110.00);
em.getTransaction().commit();
orderId = order.getId();
itemId = sonyId;
em.close();
}
@Test
public void testRevisionsCounts() throws Exception {
Assert.assertEquals(Arrays.asList(1, 2), getAuditReader().getRevisions(PurchaseOrder.class, orderId));
Assert.assertEquals(Arrays.asList(1, 3), getAuditReader().getRevisions(Item.class, itemId));
}
@Test
public void testHistoryOfPurchaseOrder() {
PurchaseOrder ver1 = new PurchaseOrder(orderId, new Item(new ItemId("TV", 1, new Producer(1, "Sony")), 100.50), null);
PurchaseOrder ver2 = new PurchaseOrder(orderId, new Item(new ItemId("TV", 1, new Producer(1, "Sony")), 100.50), "fragile");
Assert.assertEquals(ver1, getAuditReader().find(PurchaseOrder.class, orderId, 1));
Assert.assertEquals(ver2, getAuditReader().find(PurchaseOrder.class, orderId, 2));
}
@Test
public void testHistoryOfItem() {
Item ver1 = new Item(itemId, 100.50);
Item ver2 = new Item(itemId, 110.00);
Assert.assertEquals(ver1, getAuditReader().find(Item.class, itemId, 1));
Assert.assertEquals(ver2, getAuditReader().find(Item.class, itemId, 3));
}
}