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

453*_*992 2 java url hibernate hibernate-mapping hibernate-criteria

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

在我的项目中,我将“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;
}
Run Code Online (Sandbox Code Playgroud)

所以,我可以创建我的特定java类来实现org.hibenrate.UserType并尝试解决它,但我在hibernate文档中读到已经存在一个UrlType(https://docs.jboss.org/hibernate/ orm/4.2/javadocs/org/hibernate/type/UrlType.html)和这个 UrlType 只是在 varchar 和 url 之间进行映射,现在我一定很愚蠢,但我不明白如何使用它进行映射表的 varchar 与我的程序的 java.net.url 对象。无论如何,如果您知道一些拦截从 hibernate 返回的值的技巧,并且只需在其中附加字符串“http://”,也很受欢迎。

提前。问候。

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

UPDATE myTable SET url= CONCAT('http://',url) WHERE NOT url like 'http://%';
Run Code Online (Sandbox Code Playgroud)

运行所有 Hibernate 操作。

Hibernate增删改查操作后:

UPDATE myTable SET url = REPLACE(url, 'http://', '') WHERE url LIKE '%http://%';
Run Code Online (Sandbox Code Playgroud)

UPDATE2 我尝试在 setUrl(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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,当我进行 UPDATE、REMOVE、PERSIST 操作时,工作正常,但如果您想要类似“@PreLoad”(注意:此注释不存在)的内容,请将 sql 值“www.test.com”转换为“ http://” www.test.com “在java对象存储之前,我发现最简单的事情就是使用hibernate拦截器。

Vla*_*cea 5

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

您需要做的就是使用一个简单的映射,如下所示:

@Column(name = "url")
private URL url;
Run Code Online (Sandbox Code Playgroud)