7

There is an annotation in Hibernate that can persist boolean types as 'Y'/'N' in the database.

https://stackoverflow.com/questions/1154833/configure-hibernate-using-jpa-to-store-y-n-for-type-boole an-instead-of-0-1

However if I don't want to bind to Hibernate is there a way to do it in pure JPA without using getters/setters?

Community
  • 1
  • 1
newguy
  • 5,668
  • 12
  • 55
  • 95

4 Answers4

8

Pure JPA without Hibernate is achieved by using some kind of conversion

private boolean enabled;

@Transient
public boolean isEnabled() {
    return this.enabled;
}
public void setEnabled(boolean enabled) {
    this.enabled = enabled;
}

@Column(name="ENABLED")
public String getEnabledAsString(){
    return enabled ? "Y" : "N";
}

public void setEnabledAsString(String enabled){
    this.enabled = "Y".equalsIgnoreCase(enabled);
}

Nothing else

Johnny
  • 73
  • 5
Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
  • Yes, this will work (+1). I'll contact you by mail this weekend about a pending comment I didn't answer. I'm very interested by the idea so let's discuss :) – Pascal Thivent Nov 12 '10 at 09:04
  • So this is the getter/setter method. I wish there are other easier ways to workaround this. Why doesn't JPA standard provide annotation support for this? – newguy Nov 14 '10 at 22:15
  • This also doesn't deal with the situation that if the column has NULL value in the database. You can modify to get the NULL value out but when you put in it is converted to "N". – newguy Nov 14 '10 at 22:36
  • @newguy As shown above, null is handled as *false*. Sorry but **as far as i know** it is the workaround used to handle custom conversion in JPA. I use without no problem. – Arthur Ronald Nov 16 '10 at 02:25
5

This is pure JPA without using getters/setters, so it answers the question:

@Entity
public class Person {    

    @Convert(converter=BooleanToStringConverter.class)
    private Boolean isAlive;    
    ...
}

And then:

@Converter
public class BooleanToStringConverter implements AttributeConverter<Boolean, String> {

    @Override
    public String convertToDatabaseColumn(Boolean value) {        
        return (value == null || !value) ? "N" : "Y";            
        }    

    @Override
    public Boolean convertToEntityAttribute(String value) {
        return "Y".equals(value);
        }
    }

Please note this solution is JPA 2.1, and was not available when the question was first asked: The JPA 2.1 specification was released 22 April 2013.

Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
2

You can use like this

@Entity
public class Employee {
@Convert(converter=BooleanTFConverter.class)
private Boolean isActive;
}

@Converter
public class BooleanYNConverter implements AttributeConverter<Boolean, String>{
@Override
public String convertToDatabaseColumn(Boolean value) {
    if (value) {
        return "Y";
    } else {
        return "N";
    }
}
@Override
public Boolean convertToEntityAttribute(String value) {
    return "Y".equals(value);
}

}

Kalyan Das
  • 91
  • 1
  • 1
1

Similar to the above (@Arthur Ronald F D Garcia), but you can also use JPA field access and leave the ivar in the type of the database with transient accessors - marking them @Transient. This ensures JPA acces the entity by field access but leaves the accessors available for appropriately typed usage.

Using the above example:

@Column(name="isconstrained")
private int isConstrained;

@Transient
public boolean getIsConstrained() {
    return (isConstrained == 1);
}

@Transient
public void setIsConstrained(boolean isConstrained) {
    this.isConstrained = (isConstrained? 1 : 0);
}
Patrick
  • 1,717
  • 7
  • 21
  • 28
wmorrison365
  • 5,995
  • 2
  • 27
  • 40
  • The only downside to this is that you may not be able to maintain generated JPA classes - as you've tailored your accessors. If this is important, you may need to build a generator factory for your JPA classes. Not sure if this can be done with eclipse jetty? – wmorrison365 Jan 16 '13 at 10:03