cditcher
cditcher

Reputation: 358

Can I map Object type to table using JPA?

I used xjc to create a model class which represents a directory. It is annotated for use with jax-b and jpa. Because it models a directory, a directory can contain both documents (files) and other directories so one of the class properties is:

@XmlElements({
    @XmlElement(name = "dir", type = Dir.class),
    @XmlElement(name = "document", type = Document.class)
})
protected List<Object> dirOrDocument = new ArrayList<>();

You can see that I have a List of Objects which can either be an instance of a Dir or Document class. This works great for marshalling to xml using jax-b but if I want to persist this to a database using JPA, how would i tell JPA to test if Object is instanceof Dir, write to Dir table. If Object is instanceof Document, write to document table?

I have looked at using JPA AttributeConverter, but doesn't look promising as it seems to convert from one type to another, but i need to potentially convert to multiple types.

Perhaps there is another way to represent my model that can be used better for both JAXB and JPA?

I am using eclipselink for both JAXB and JPA implementations.

Upvotes: 1

Views: 559

Answers (2)

cditcher
cditcher

Reputation: 358

Update: I was able to resolve this issue by using inheritance as suggested by JB Nizet. I created an abstract entity class as such:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@XmlTransient
public abstract class CNode {

@Id
@GeneratedValue
@Column(name = "nodeId")
@XmlTransient
protected int nodeId;

// getters and setters
}

and converted the List to:

@XmlElements({
    @XmlElement(name = "dir", type = Dir.class),
    @XmlElement(name = "document", type = Document.class)
})
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch=FetchType.LAZY, orphanRemoval=true)
protected List<CNode> dirOrDocument = new ArrayList<>();

I then made my Dir.class and Document.class extend my CNode.class. Now everything works using jaxb and jpa.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691715

Either make it two separate associations (subDirectories, and documents), or create an abstract entity (File for example) containing the common fields (name, parentDirectory, etc.), and two subclasses Directory and Document. Then read the Hibernate manual chapter about inheritance to understand the various ways of mapping inheritance.

Upvotes: 1

Related Questions