Tagged: java

Injecting Property Values into EJBs from Database


references

Property.java

@Entity
@NamedQueries({
@NamedQuery(name = "Property.find",
            query = "SELECT p FROM Property AS p WHERE p.name = :name")
})
public class Property {

    @Basic(optional = false)
    @Column(name = "NAME", nullable = false, unique = true)
    @NotNull
    private String name;

    @Basic(Optional = false)
    @Column(name = "VALUE_", nullable = false)
    @NotNull
    private String value = "";
}

find

public static Property findNamed(final EntityManager entityManager,
                                 final String name) {
    final TypedQuery typedQuery
        = entityManager.createNamedQuery("Property.find", Property.class);
    typedQuery.setParameter("name", name);
    try {
        return typedQuery.getSingleResult();
    } catch (final NoResultException nre) {
        return null;
    }
}

public static Property findCriteria(final EntityManager entityManager,
                                    final String name) {
    final CriteriaBuilder criteriaBuilder
        = entityManager.getCriteriaBuilder();
    final CriteriaQuery criteriaQuery
        = criteriaBuilder.createQuery(Property.class);
    final Root<Property> property = criteriaQuery.from(Property.class);
    criteriaQuery.select(property);
    criteriaQuery.where(
        criteriaBuilder.equal(property.get(Property_.name), name));
    final TypedQuery typedQuery
        = entityManager.createQuery(criteriaQuery);
    try {
        return typedQuery.getSingleResult();
    } catch (final NoResultException nre) {
        return null;
    }
}

public static Property find(final EntityManager entityManager,
                            final String name) {
    if (current().nextBoolean()) {
        return findNamed(entityManager, name);
    }
    return findCriteria(entityManager, name);
}

PropertyValue.java

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, METHOD, PARAMETER, TYPE})
public @interface PropertyValue {

    @Nonbinding
    String name() default "";

    @Nonbinding
    boolean optional() default true;
}

PropertyFactory.java

@Dependent
public class PropertyValueFactory {

@Produces
@PropertyValue
public String producePropertyValue(final InjectionPoint injectionPoint) {
    final PropertyValue annotation
        = injectionPoint.getAnnotated().getAnnotation(PropertyValue.class);
    final String name = annotation.name();
    final boolean optional = annotation.optional();
    final Property property = Property.find(entityManger, name);
    if (property == null && !optional) {
        throw new InjectionException("property not found; name= " + name);
    }
    return ofNullable(property).map(Property::getValue).orElse(null);
}

public void diposePropertyValue(
    @Disposes @PropertyValue final String value) {
    // empty


@PersistenceContext
private EntityManager entityManger;
}

StorageObjectServiceFtp.java

 @Stateless
 public class StorageObjectServiceFtp extends StorageObjectService {

    @Inject
    @PropertyValue(name = "ftp.hostname", optional = false)
    private String hostname;

    @Inject
    @PropertyValue(name = "ftp.username", optional = false)
    private String username;

    @Inject
    @PropertyValue(name = "ftp.password", optional = false)
    private String password;

    @Inject
    @PropertyValue(name = "ftp.rootpath", optional = true)
    private String rootpath;
}

orElse, or orElseGet, that is the question:


static String B() {
    System.out.println("B()...");
    return "B";
}

public static void main(final String... args) {
    System.out.println(Optional.of("A").orElse(B()));
    System.out.println(Optional.of("A").orElseGet(() -> B()));
}

format/parse ISO 8601 ignoring the fraction


    static Instant parseIsoInstant(final String formatted) {
        return Instant.from(DateTimeFormatter.ISO_INSTANT.parse(formatted))
                .with(ChronoField.NANO_OF_SECOND, 0L);
    }

    static String formatIsoInstant(final TemporalAccessor parsed) {
        return DateTimeFormatter.ISO_INSTANT.format(
                Instant.from(parsed).with(ChronoField.NANO_OF_SECOND, 0L));
    }

    static Date parseIsoDate(final String formatted) {
        return Date.from(parseIsoInstant(formatted));
    }

    static String formatIsoDate(final Date parsed) {
        return formatIsoInstant(parsed.toInstant());
    }

how to set final variable in catch block?


references

as final as possible, but not final-er.

꽤나 오랫동안 궁금했었다.

final SecureRandom random;
try {
    random = SecureRandom.getInstanceStrong();
} catch (final NoSuchAlgorithmException nsae) {
    random = new SecureRandom(); // won't compile
    // variable random might already have been assigned
}

let it go, let it go~~~

그냥 이렇게 하면 되지 뭐…

SecureRandom random;
try {
    random = SecureRandom.getInstanceStrong();
} catch (final NoSuchAlgorithmException nsae) {
    random = new SecureRandom();
}

// ----------------------------------
// 권팀장 죽어버려!!! -퇴사자-
random = null;
// ----------------------------------

final int i = random.nextInt(128); // NPE

we will find a way. we always have.

지저분해 보일지도 모르겠다.

final SecureRandom random;
{
    Random random_;
    try {
        random_ = SecureRandom.getInstanceStrong();
    } catch (final NoSuchAlgorithmException nsae) {
        random_ = new SecureRandom();
    }
    random = random_;
}

메서드로 따로 빼 놓고 써도 되고, 뭐…

static SecureRandom secureRandomPossiblyStrong() {
    try {
        return SecureRandom.getInstanceStrong();
    } catch (final NoSuchAlgorithmException nsae) {
        return new SecureRandom();
    }
}

Supplier 를 사용해도 될 듯…

final static SecureRandom RANDOM =
    ((Supplier<SecureRandom>)() ->{
        try {
            return SecureRandom.getInstanceStrong();
        } catch (final NoSuchAlgorithmException nsae) {
            return new SecureRandom();
        } 
    }).get();

 

exclusive or with java


references

^

XOR 을 사용할 일은 많이 없을 듯 하지만, 의외로 사용할 일이 있을 때 모르고 지나치는 일이 있다. 아래 코드는 condition1condition2중 하나만 true 일 때 특정 작업을 수행하는 코드이다.

void some() {
    if (condition1) {
        if (!condition2) {
            // do some!                     // T F
            return;
        }
    } else { // !condition1
        if (condition2) {
            // do some!                     // F T
            return;
        }
    }
    assert (condition1 && condition2)       // T T
           || (!condition1 && !condition2); // F F
}

Exclusive OR 를 다음과 같이 사용할 수 있다.

void some() {
    if (condition1 ^ condition2) {            // T F | F T
        // do some!
    }
}

When are generated primary key values available?


JSR 338: JavaTM Persistence 2.1 says, in 3.5.3, that

Generated primary key values are available in the PostPersist method.

It’s a pity that even those ids with GenerationType.TABLE are not available in the PrePersist method and it’s a bigger pity that I didn’t rely on the spec.

public class MyEntity {

    @PrePersist
    private void onPrePersist() {
        derived = Stirng.format("%1$016x", id);
    }

    @GeneratedValue(generator = "some",
                    strategy = GenerationType.TABLE)
    @TableGenerator(
            ...
            name = "some",
            ...
    )
    @NotNull
    private Long id;

    @Basic(optional = false)
    @Column(name = "DERIVED", nullable = false, updatable = false)
    @NotNull
    private String derived;
}

I just found that above code doesn’t work with WildFly while works with Payara.

I have to change my database and the code.

public class MyEntity {

    @PrePersist
    private void onPrePersist() {
        //derived = Stirng.format("%1$016x", id);
    }

    @PostPersist
    private void onPostPersist() {
        derived = Stirng.format("%1$016x", id);
    }

    @GeneratedValue(generator = "some",
                    strategy = GenerationType.TABLE)
    @TableGenerator(
            ...
            name = "some",
            ...
    )
    @NotNull
    private Long id;

    @Basic // optional
    @Column(name = "DERIVED") // nullable, updatable
    //@NotNull
    private String derived;
}

diagnosing system with jax-rs


@Path("/system/diagnoses")
public class DiagnosesResource {

    private static final Logger logger
            = getLogger(DiagnosesResource.class.getName());

    private Response response() {
        handler.flush();
        return Response.ok(baos.toByteArray(), MediaType.TEXT_PLAIN).build();
    }

    @PostConstruct
    private void onPostConstruct() {
        baos = new ByteArrayOutputStream();
        formatter = new SimpleFormatter();
        handler = new StreamHandler(baos, formatter);
        logger.addHandler(handler);
    }

    @PreDestroy
    private void onPreDestroy() {
        logger.removeHandler(handler);
        handler = null;
        formatter = null;
        baos = null;
    }

    private ByteArrayOutputStream baos;

    private Formatter formatter;

    private Handler handler;
}

Now we can add some methods for diagnosing.

@POST
@Path("/some")
@Produces({MediaType.TEXT_PLAIN})
public Response some() {
    // diagnose here with some logs
    return response();
}

finding an entity by its unique attribute value.


    public static <T extends BaseEntity, Y> Optional<T> findByUniqueAttribute(
            final EntityManager entityManager,
            final Class<T> entityClass,
            final Supplier<SingularAttribute<? super T, Y>> attributeSupplier,
            final Supplier<? extends Y> valueSupplier) {
        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<T> criteria = builder.createQuery(entityClass);
        final Root<T> root = criteria.from(entityClass);
        criteria.select(root);
        criteria.where(builder.equal(root.get(
                attributeSupplier.get()), valueSupplier.get()));
        try {
            return Optional.of(
                    entityManager.createQuery(criteria).getSingleResult());
        } catch (final NoResultException nre) {
            return Optional.empty();
        }
    }
    public static <T extends BaseEntity, Y> Optional<T> findByUniqueAttribute2(
            @NotNull final EntityManager entityManager,
            @NotNull final Class<T> entityClass,
            @NotNull final Function<ManagedType<T>, SingularAttribute<? super T, Y>> attributeSupplier,
            @NotNull final Supplier<? extends Y> valueSupplier) {
        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<T> criteria = builder.createQuery(entityClass);
        final Root<T> root = criteria.from(entityClass);
        criteria.select(root);
        criteria.where(builder.equal(
                root.get(attributeSupplier.apply(
                        entityManager.getMetamodel().entity(entityClass))),
                valueSupplier.get()));
        try {
            return Optional.of(
                    entityManager.createQuery(criteria).getSingleResult());
        } catch (final NoResultException nre) {
            return Optional.empty();
        }
    }