2020-04-29

Hibernate JPA @CollectionType Example

@CollectionType

The @CollectionType annotation is used to specify a custom collection type.

The collection can also name a @Type, which defines the Hibernate Type of the collection elements.

CollectionType Names a custom collection type for a persistent collection. The collection can also name a @Type, which defines the Hibernate Type of the collection elements.

Custom collection mapping example

@Entity(name = "Person")
public static class Person {

@Id
private Long id;

@OneToMany(cascade = CascadeType.ALL)
@CollectionType( type = "org.hibernate.userguide.collections.type.QueueType")
private Collection<Phone> phones = new LinkedList<>();

//Constructors are omitted for brevity

public Queue<Phone> getPhones() {
return (Queue<Phone>) phones;
}
}

@Entity(name = "Phone")
public static class Phone implements Comparable<Phone> {

@Id
private Long id;

private String type;

@NaturalId
@Column(name = "`number`")
private String number;

//Getters and setters are omitted for brevity

@Override
public int compareTo(Phone o) {
return number.compareTo( o.getNumber() );
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Phone phone = (Phone) o;
return Objects.equals( number, phone.number );
}

@Override
public int hashCode() {
return Objects.hash( number );
}
}

public class QueueType implements UserCollectionType {

    @Override
    public PersistentCollection instantiate(
            SharedSessionContractImplementor session,
            CollectionPersister persister) throws HibernateException {
        return new PersistentQueue( session );
    }

    @Override
    public PersistentCollection wrap(
            SharedSessionContractImplementor session,
            Object collection) {
        return new PersistentQueue( session, (List) collection );
    }

    @Override
    public Iterator getElementsIterator(Object collection) {
        return ( (Queue) collection ).iterator();
    }

    @Override
    public boolean contains(Object collection, Object entity) {
        return ( (Queue) collection ).contains( entity );
    }

    @Override
    public Object indexOf(Object collection, Object entity) {
        int i = ( (List) collection ).indexOf( entity );
        return ( i < 0 ) ? null : i;
    }

    @Override
    public Object replaceElements(
            Object original,
            Object target,
            CollectionPersister persister,
            Object owner,
            Map copyCache,
            SharedSessionContractImplementor session)
            throws HibernateException {
        Queue result = (Queue) target;
        result.clear();
        result.addAll( (Queue) original );
        return result;
    }

    @Override
    public Object instantiate(int anticipatedSize) {
        return new LinkedList<>();
    }

}

public class PersistentQueue extends PersistentBag implements Queue {

    public PersistentQueue(SharedSessionContractImplementor session) {
        super( session );
    }

    public PersistentQueue(SharedSessionContractImplementor session, List list) {
        super( session, list );
    }

    @Override
    public boolean offer(Object o) {
        return add(o);
    }

    @Override
    public Object remove() {
        return poll();
    }

    @Override
    public Object poll() {
        int size = size();
        if(size > 0) {
            Object first = get(0);
            remove( 0 );
            return first;
        }
        throw new NoSuchElementException();
    }

    @Override
    public Object element() {
        return peek();
    }

    @Override
    public Object peek() {
        return size() > 0 ? get( 0 ) : null;
    }
}

No comments:

Post a Comment