使用 Hibernate 将 SQL 列的 varchar 类型映射到 Java 的 java.net.URL

Mapping varchar type of a SQL column to a java.net.URL of Java with Hibernate

我在 table 中有一列(名为 "url"),其值为 URL。有些存储为“http://www.test.com”,而另一些存储为“blogspot.sometest.com”(顺便说一下,table 不是我的,所以我无法更改结构)。

在我的项目中,我将 "url" 列的内容存储为结构化对象的 java.net.URL 类型 属性(例如 Page(String name,URL url);)。所以,如果可以的话,我不想修改项目。

我希望使用 Hibernate 能够获取具有特定 ID 的单个记录。示例代码:

 @Override
public T selectRow(Serializable id){
    T object = null;
    try {
        openSession();
        trns = session.beginTransaction();
        criteria = session.createCriteria(cl);
                 criteria.add(org.hibernate.criterion.Restrictions.eq("doc_id",id));
        //THIS LINE OF CODE LAUNCH THE EXCEPTION: org.hibernate.HibernateException: Unable to convert string [4bid.it] to URL : java.net.MalformedURLException: no protocol: 4bid.it 
       //BECAUSE FOR SOME OF THE URLS THERE IS NO PROTOCOL...
        List<T> results = criteria.list();
        //SAME WITH THIS
        object = (T) criteria.setFirstResult((Integer) id);

    //THE NEXT LINE OF CODE WORK BUT RETURN NULL FOR URL WITHOUT THE PROTOCOL
    object = (T) session.load(cl, id); 
    } catch (RuntimeException e) {
        if (trns != null) { trns.rollback();}
        SystemLog.exception(e);
    } finally {
        session.flush();
        session.close();
    }
    return object;
}

所以,我可以创建我的特定 java class 来实现 org.hibenrate.UserType 并尝试解决这个问题,但我在休眠文档中读到已经存在 UrlType (https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/type/UrlType.html) 和这个 UrlType 只是做 varchar 和 url 之间的映射,现在我一定是愚蠢的,但我不明白怎么可能我用它来映射 table 的 varchar 和我程序的 java.net.url 对象。 如果无论如何你知道一些拦截从休眠返回的值的技巧并且只需将字符串 "http://" 附加到它也欢迎。

提前联系。你好。

更新 1: 我的问题的强力解决方案是执行两个 SQL 查询: 在 CRUD 休眠操作之前:

UPDATE myTable SET url= CONCAT('http://',url) WHERE NOT url like 'http://%';

运行所有休眠操作。

CRUD Hibernate运行后:

UPDATE myTable SET url = REPLACE(url, 'http://', '') WHERE url LIKE '%http://%';

更新2 我已经尝试在集合 Url(Url url) 上使用 @PreUpdate 和 @PrePersist 注释,如下所示:

@PreUpdate
@PrePersist
public void setUrl(URL url) {
    if(url.toString().contains("://")) {
        this.url = url;
    }else{
        try {
            this.url = new URL("http://"+url.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

现在当我只进行更新、删除、持久操作时工作正常,但是如果你想要像“@PreLoad”这样的东西(注意:这个注释不存在)来转换 sql 值 "www.test.com" 到 java 对象上存储之前的“http://www.test.com” 我发现最简单的事情就是使用休眠拦截器。

已经支持 UrlType,它将 VARCHAR 列映射到 java.net.URL 属性。

您需要做的就是使用这样一个简单的映射:

@Column(name = "url")
private URL url;