Как заставить Hibernate добавлять кавычки в сгенерированные операторы SQL? - PullRequest
2 голосов
/ 29 октября 2010

Hibernate генерирует недопустимый SQL для запроса определенного критерия.Я могу вручную исправить запрос, добавив одинарные кавычки к значению, используемому в предложении WHERE.

Чтобы исправить это, я изменил запрос с:

where (role0_.ROLE_ID=2L )

на:

where (role0_.ROLE_ID=`2L` )

Как заставить hibernate добавлять одинарные кавычки (в mysql это одинарные кавычки, но в других системах баз данных это может быть что-то еще) для включения значений , используемых в сгенерированных запросах SQL?

Полный сгенерированный запрос:

select permission1_.PERMISSION_ID as PERMISSION1_12_,
    permission1_.IS_REQUIRED as IS2_12_,
    permission1_.SOURCE_ROLE_ID as SOURCE3_12_,
    permission1_.TARGET_ROLE_ID as TARGET4_12_
from (
        select ROLE_ID,
        NAME,
        DESCRIPTION,
        IS_ACTION,
        LABEL,
        null as FIRST_NAME,
        null as LAST_NAME,
        null as PASSWORD_HASH,
        1 as clazz_ from GROUPS
    union
        select ROLE_ID,
            NAME,
            null as DESCRIPTION,
            null as IS_ACTION,
            null as LABEL,
            FIRST_NAME,
            LAST_NAME,
            PASSWORD_HASH,
            2 as clazz_ from USERS
    )
role0_ inner join PERMISSIONS permission1_ on role0_.ROLE_ID=permission1_.SOURCE_ROLE_ID
    where (role0_.ROLE_ID=2L )

По сути, я бы хотел, чтобы Hibernate добавил эти одинарные кавычки.

Критерий запроса, который сгенерировал этот запрос:

EntityManager entityManager = getEntityManager();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

Class<?> queryScopeClass = temp.pack.commons.user.Role.class;
Root<?> from = criteriaQuery.from(queryScopeClass);

Path<?> idAttrPath = from.get("id");
// also tried criteriaBuilder.equal(idAttrPath, new Long(2))
Predicate predicate = criteriaBuilder.equal(idAttrPath, criteriaBuilder.literal(new Long(2)))
criteriaQuery.where(predicate);

Path<?> attributePath = from.get("permissions");
PluralAttributePath<?> pluralAttrPath = (PluralAttributePath<?>)attributePath;
PluralAttribute<?, ?, ?> pluralAttr = pluralAttrPath.getAttribute();

Join<?, ?> join = from.join((SetAttribute<Object,?>)pluralAttr);

TypedQuery<Object> typedQuery = entityManager.createQuery(criteriaQuery.select(join));
return (List<P>)typedQuery.getResultList();

Пожалуйста, дайте мне знать, если у вас есть какие-либо подсказки о том, как заставить Hibernate добавлять эти одинарные кавычки в значения (не имя столбца / таблицы).

В моей роли сущностиКонечно, свойство id, отображаемое в предложении WHERE, имеет тип long.

Follow: Тип столбца id в базе данных: bingint:

+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| ROLE_ID       | bigint(20)   | NO   | PRI | NULL    |       |

...

Вот как аннотируется класс Role:

@Entity(name="Role")
@Table(name = "ROLES")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@javax.persistence.TableGenerator(
    name="GENERATED_IDS",
    table="GENERATED_IDS",
    valueColumnName = "ID"
)
public abstract class Role implements Serializable {
    private static final long serialVersionUID = 1L;


    /**
     * The id of this role. Internal use only.
     * 
     * @since 1.0
     */
    @Id @GeneratedValue(strategy = GenerationType.TABLE, generator="GENERATED_IDS")
    @Column(name = "ROLE_ID")
    protected long id;


    /**
     * Set of permissions granted to this role.
     * 
     * @since 1.0
     */
    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy="sourceRole")
    protected Set<Permission> permissions = new HashSet<Permission>();

...

}

Я использую стратегию наследования таблиц для каждого класса, поэтому вы видите объединение в сгенерированном запросе для сущностей пользователя и группы.Они расширяют роль.Идентификатор определен в роли.

Спасибо!

Эдуардо

Ответы [ 2 ]

6 голосов
/ 12 августа 2015

Свойство гибернации hibernate.globally_quoted_identifiers = true добьется цели

1 голос
/ 29 октября 2010

Измените свой идентификатор на тип класса Long вместо примитива.Затем Hibernate просто сгенерирует запрос, который будет иметь значение ROLE_ID = 2, что на 100% допустимо, поскольку числа не требуют тиков или кавычек.

...