java – Yon Labs http://www.yonlabs.com Yon Labs Wed, 07 Sep 2022 00:57:03 +0000 en-US hourly 1 https://wordpress.org/?v=6.2 http://www.yonlabs.com/wp-content/uploads/2021/01/yonita-square.png java – Yon Labs http://www.yonlabs.com 32 32 How to Detect Long Running Queries in Hibernate? http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/ http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/#respond Wed, 18 Aug 2021 00:28:00 +0000 http://www.yonlabs.com/?p=368 Read more

]]>
Most Java applications use Jakarta Persistence API (formerly Java Persistence API) to access databases. Hibernate is the most popular ORM framework for Java. It is a straightforward and easy-to-use implementation of JPA. However, its simplicity of usage often becomes mischievous to developers and leads to serious performance issues in Hibernate-based applications. How to detect such issues? The answer might lay in smart logging.

Logging Slow Queries

Hibernate supports logging queries that run longer than a specified amount of time in miliseconds. To configure this feature you need to use parameter hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS. This parameter can be very helpful in detecting bottlenecks in production systems without producing excessive number of logs.

Example:

hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=1000

Logging Queries with Parameters

When we tune or debug our applications, it often happens that we are interested not only in executed SQL/JPQL/HQL queries but also in parameters bound for a given query. Actually, that may be a crucial piece of information! Unfortunately, the widely-known show-sql logs only SQL queries without bound parameters.

In order to log queries along with bound parameters, you can use:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

]]>
http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/feed/ 0
How to Map PostgreSQL BIT with Hibernate http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/ http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/#respond Thu, 22 Jul 2021 20:41:00 +0000 https://www.yonlabs.com/?p=323 Unfortunately, Jakarta Persistence API (formerly Java Persistence API aka JPA) does not support BIT having a parametrised length. Fortunately, hibernate (one of the implementation of JPA) supports custom types, thus you can define your own BIT type with a parametrised length.

Custom Definition of BIT

First, you need to create BitStringTypeBitStringJavaDescriptor, and BitStringSqlDescriptor:

public class BitStringType extends AbstractSingleColumnStandardBasicType<String> {

    public static final BitStringType INSTANCE = new BitStringType();

    public BitStringType() {
        super(VarcharTypeDescriptor.INSTANCE, BitStringJavaDescriptor.INSTANCE);
    }

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

}
public class BitStringJavaDescriptor extends AbstractTypeDescriptor<String> {

    public static final BitStringJavaDescriptor INSTANCE = new BitStringJavaDescriptor();

    public BitStringJavaDescriptor() {
        super(String.class, ImmutableMutabilityPlan.INSTANCE);
    }

    @Override
    public String fromString(String string) {
        return string;
    }

    @Override
    public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
        if (value == null)
            return null;
        if (String.class.isAssignableFrom(type))
            return (X) value;
        throw unknownUnwrap(type);
    }

    @Override
    public <X> String wrap(X value, WrapperOptions options) {
        if (value == null)
            return null;
        if (String.class.isInstance(value))
            return (String) value;
        throw unknownWrap(value.getClass());
    }

}
    @Override
    public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>(javaTypeDescriptor, this) {
            @Override
            protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
                st.setObject(index, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
            }
            @Override
            protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException {
                st.setObject(name, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
            }
        };
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicExtractor<X>(javaTypeDescriptor, this) {
            @Override
            protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(rs.getString(name), options);
            }
            @Override
            protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(statement.getString(index), options);
            }
            @Override
            protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(statement.getString(name), options);
            }
        };
    }

}

Use Your Custom BIT Type

Having those classes, you can define a type for your field. Please, use the correct package (in my case I’ve used the one from my demo com.yonlabs.jpa):

    @Column
    @Type(type = "com.yonlabs.jpa.BitStringType")
    private String bits;

You can also register this type with hibernate to use a registered name instead of a fully qualified Java class.

]]>
http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/feed/ 0