Skip to content

Commit

Permalink
Add support for the JavaMoney (JSR 354) CurrencyUnit #473
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrooo authored and vladmihalcea committed Aug 15, 2022
1 parent a571dbe commit 00ad3ac
Show file tree
Hide file tree
Showing 23 changed files with 971 additions and 42 deletions.
10 changes: 0 additions & 10 deletions hibernate-types-4/pom.xml
Expand Up @@ -47,15 +47,6 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>${moneta.version}</version>
<type>pom</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
Expand All @@ -79,7 +70,6 @@

<jackson-databind.version>2.12.6.1</jackson-databind.version>
<guava.version>12.0</guava.version>
<moneta.version>1.4.2</moneta.version>
</properties>

<build>
Expand Down
10 changes: 0 additions & 10 deletions hibernate-types-43/pom.xml
Expand Up @@ -47,15 +47,6 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>${moneta.version}</version>
<type>pom</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
Expand All @@ -79,7 +70,6 @@

<jackson-databind.version>2.12.6.1</jackson-databind.version>
<guava.version>12.0</guava.version>
<moneta.version>1.4.2</moneta.version>
</properties>

<build>
Expand Down
10 changes: 0 additions & 10 deletions hibernate-types-5/pom.xml
Expand Up @@ -47,15 +47,6 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>${moneta.version}</version>
<type>pom</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
Expand All @@ -79,7 +70,6 @@

<jackson-databind.version>2.12.6.1</jackson-databind.version>
<guava.version>12.0</guava.version>
<moneta.version>1.4.2</moneta.version>
</properties>

<build>
Expand Down
Expand Up @@ -6,6 +6,7 @@
import com.vladmihalcea.hibernate.type.interval.PostgreSQLIntervalType;
import com.vladmihalcea.hibernate.type.interval.PostgreSQLPeriodType;
import com.vladmihalcea.hibernate.type.json.*;
import com.vladmihalcea.hibernate.type.money.CurrencyUnitType;
import com.vladmihalcea.hibernate.type.money.MonetaryAmountType;
import com.vladmihalcea.hibernate.type.range.PostgreSQLRangeType;
import com.vladmihalcea.hibernate.type.range.guava.PostgreSQLGuavaRangeType;
Expand Down Expand Up @@ -98,7 +99,8 @@ public void contribute(TypeContributions typeContributions, ServiceRegistry serv
.contributeType(typeContributions, JsonType.INSTANCE);
/* Money and Currency API */
if(ReflectionUtils.getClassOrNull("org.javamoney.moneta.Money") != null) {
this.contributeType(typeContributions, MonetaryAmountType.INSTANCE);
this.contributeType(typeContributions, CurrencyUnitType.INSTANCE)
.contributeType(typeContributions, MonetaryAmountType.INSTANCE);
}
}

Expand Down
@@ -0,0 +1,39 @@
package com.vladmihalcea.hibernate.type.money;

import com.vladmihalcea.hibernate.type.AbstractHibernateType;
import com.vladmihalcea.hibernate.type.money.internal.CurrencyUnitTypeDescriptor;
import com.vladmihalcea.hibernate.type.util.Configuration;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;

import javax.money.CurrencyUnit;

/**
* Maps a Java {@link CurrencyUnit} object to a {@code VARCHAR} column type.
*
* @author Piotr Olaszewski
*/
public class CurrencyUnitType extends AbstractHibernateType<CurrencyUnit> {
public static final CurrencyUnitType INSTANCE = new CurrencyUnitType();

public CurrencyUnitType() {
super(VarcharTypeDescriptor.INSTANCE, CurrencyUnitTypeDescriptor.INSTANCE);
}

public CurrencyUnitType(Configuration configuration) {
super(
VarcharTypeDescriptor.INSTANCE,
CurrencyUnitTypeDescriptor.INSTANCE,
configuration
);
}

@Override
public String getName() {
return "currency";
}

@Override
protected boolean registerUnderJavaType() {
return true;
}
}
@@ -0,0 +1,50 @@
package com.vladmihalcea.hibernate.type.money.internal;

import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;

import javax.money.CurrencyUnit;
import javax.money.Monetary;

/**
* @author Piotr Olaszewski
*/
public class CurrencyUnitTypeDescriptor extends AbstractTypeDescriptor<CurrencyUnit> {

public static final CurrencyUnitTypeDescriptor INSTANCE = new CurrencyUnitTypeDescriptor();

public CurrencyUnitTypeDescriptor() {
super(CurrencyUnit.class);
}

@Override
public CurrencyUnit fromString(String string) {
return Monetary.getCurrency(string);
}

@Override
public <X> X unwrap(CurrencyUnit value, Class<X> type, WrapperOptions options) {
if (value == null) {
return null;
}

if (String.class.isAssignableFrom(type)) {
return (X) value.getCurrencyCode();
}

throw unknownUnwrap(type);
}

@Override
public <X> CurrencyUnit wrap(X value, WrapperOptions options) {
if (value == null) {
return null;
}

if (value instanceof String) {
return fromString((String) value);
}

throw unknownWrap(value.getClass());
}
}
@@ -0,0 +1,118 @@
package com.vladmihalcea.hibernate.type.money;

import com.vladmihalcea.hibernate.util.AbstractMySQLIntegrationTest;
import org.hibernate.annotations.TypeDef;
import org.junit.Test;

import javax.money.CurrencyUnit;
import javax.persistence.*;

import static javax.money.Monetary.getCurrency;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

/**
* @author Piotr Olaszewski
*/
public class MySQLCurrencyUnitTypeTest extends AbstractMySQLIntegrationTest {
@Override
protected Class<?>[] entities() {
return new Class[]{
Order.class
};
}

@Test
public void testPersistAndReadCurrency() {
Order _order = doInJPA(entityManager -> {
Order order = new Order();
order.setCurrency(getCurrency("EUR"));

entityManager.persist(order);

return order;
});

doInJPA(entityManager -> {
Order order = entityManager.find(Order.class, _order.getId());

assertEquals(order.getCurrency(), getCurrency("EUR"));
});
}

@Test
public void testSearchByCurrency() {
doInJPA(entityManager -> {
Order order1 = new Order();
order1.setCurrency(getCurrency("EUR"));
entityManager.persist(order1);

Order order2 = new Order();
order2.setCurrency(getCurrency("PLN"));
entityManager.persist(order2);
});

doInJPA(entityManager -> {
CurrencyUnit currency = getCurrency("PLN");
Order order = entityManager.createQuery("select o from Order o where o.currency = :currency", Order.class)
.setParameter("currency", currency)
.getSingleResult();

assertEquals(Long.valueOf(2), order.getId());
});
}

@Test
public void testReturnNullCurrency() {
Long _id = doInJPA(entityManager -> {
Order order = new Order();
entityManager.persist(order);

return order.getId();
});

doInJPA(entityManager -> {
Order order = entityManager.createQuery("select o from Order o where o.id = :id", Order.class)
.setParameter("id", _id)
.getSingleResult();

assertNull(order.getCurrency());
});

doInJPA(entityManager -> {
CurrencyUnit currency = entityManager.createQuery("select o.currency from Order o where o.id = :id", CurrencyUnit.class)
.setParameter("id", _id)
.getSingleResult();

assertNull(currency);
});
}

@Entity(name = "Order")
@Table(name = "orders")
@TypeDef(typeClass = CurrencyUnitType.class, defaultForType = CurrencyUnit.class)
public static class Order {
@Id
@GeneratedValue
private Long id;

@Column(name = "currency", columnDefinition = "char(3)")
private CurrencyUnit currency;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public CurrencyUnit getCurrency() {
return currency;
}

public void setCurrency(CurrencyUnit currency) {
this.currency = currency;
}
}
}
Expand Up @@ -57,7 +57,7 @@ public void testSearchByMoney() {

doInJPA(entityManager -> {
Money money = Money.of(new BigDecimal("10.23"), "USD");
Salary salary = entityManager.createQuery("select s from Salary s where salary = :salary", Salary.class)
Salary salary = entityManager.createQuery("select s from Salary s where s.salary = :salary", Salary.class)
.setParameter("salary", money)
.getSingleResult();

Expand Down

0 comments on commit 00ad3ac

Please sign in to comment.