【问题标题】:Java Hibernate populate transient propertyJava Hibernate 填充瞬态属性
【发布时间】:2014-01-15 21:08:54
【问题描述】:

我有几个具有临时属性的实体,我想从 sql 查询中填充这些属性。我已经尝试了几件事,但还没有找到正确的组合。

这是一个示例实体

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
long id;
@Size(max=1000)
String image_url;

@Transient
boolean liked;

@Transient
long numLikes;

**getters and setters** for persistent properties

    public boolean isLiked() {
    return liked;
}

public void setLiked(boolean liked) {
    this.liked = liked;
}

public long getNumLikes() {
    return numLikes;
}

public void setNumLikes(long numLikes) {
    this.numLikes = numLikes;
}

我尝试过使用@Basic 注释并将其获取方法设置为渴望

@Basic(fetch = FetchType.EAGER)

在吸气剂上,但这似乎没有任何作用。我也看到它设置为懒惰。

我是否在此处遗漏了任何会导致列名未映射到这些瞬态属性之一的内容?

这是我的实现代码。

SQLQuery query = getCurrentSession().createSQLQuery("" +
            "SELECT * ,count(likes1.liked) as numLikes " +
            "FROM aboutme " +
            "left JOIN " +
            "(" +
            "   select liked, likedObject_id " +
            "   from likes " +
            "   where liked = 1" +
            ") as likes1 ON aboutme.id = likes1.likedObject_id " +
            "left join " +
            "(" +
            "   select likedObject_id, liked " +
            "   from likes " +
            "   where liked = 1 and profile_id = :id" +
            ") as likes2 on likes2.likedObject_id = aboutme.id " +
            "WHERE aboutme.profile_id = :id " +
            "group by aboutme.id");

    query.addEntity(AboutMe.class);
    query.setParameter("id",id);

    return query.list();

我尝试过使用

  SQLQuery query = ..."Select count(value that returns properly) as {object.numLikes}..."


 query.addEntity("object",Object.class),

我在此处收到一条错误消息,提示找不到别名 [alias] 的属性 [property] 的列名

我做错了什么?

瞬态属性可能不是我想要做的事情。我需要弄清楚的是如何将这些派生列映射到我可以返回到前端的对象。如何设置一个对象,让 hibernate 可以将这些别名列映射到属性?

【问题讨论】:

  • Transient 标记为永远不应参与数据库持久性的字段/方法。他们并不执着。为什么还要对这些字段进行这样的注释,原因是什么?
  • 好吧,也许瞬态属性不是我需要走的路线。我有一对多的关系。对于喜欢的部分。也许我应该在列表中返回两个对象并以这种方式运行它?有没有办法返回不属于表实体的派生属性?你是怎么做的/看到这个做的?

标签: java sql spring hibernate


【解决方案1】:

我想通了。您可以设置瞬态属性,尽管这有点痛苦。

使用 SQLQuery 对象上的 addScalar 方法可以设置瞬态属性。但是,如果这样做,您必须以这种方式设置对象中的所有属性(Hibernate 不会自动填充任何属性)

您还必须在 SQLQuery 对象上使用 setResultTransformer 方法。因此,要完成我之前的示例,我必须在我的 impl 中添加以下代码。

 //  query.addEntity(AboutMe.class); <- this contradicts the setResultTransformer
 query.setParameter("id",id);

 query.addScalar("id",StandardBasicTypes.LONG);
 query.addScalar("image_url",StandardBasicTypes.LONG);
 query.addScalar("liked",StandardBasicTypes.LONG);
 query.addScalar("numLikes",StandardBasicTypes.LONG);

 query.setResultTransformer(Transformers.aliasToBean(Object.class));

其中 Object 是我想要使用的类,它声明了所有这些属性。

【讨论】:

  • 我觉得你在这里试图让你的项目变得非常复杂,这是不必要的。也许应该看看您的数据模型或查看一些如何将事情做得更好的示例。对我来说,您似乎正试图摆脱 Hibernate 的意义。
  • 好的。让我重新表述一下这个问题,我如何将未保存在同一个表中的派生数据放入一个对象中并返回它。到目前为止,这是我见过的唯一方法。或塞进pojo,但那将是相同的过程。
  • @C-Rad 我相信你的问题说得很好。我希望做同样的事情,但如果可能的话,还不清楚如何去做。
【解决方案2】:

Hibernate 永远不会填充您的瞬态字段,最重要的瞬态字段甚至不是 java 序列化过程的一部分。如果你真的需要这个,我会尝试 - 是ResultTransformer.alliasToBean,它通过反射将值“注入”到类中。

setResultTransformer(Transformers.aliasToBean(Yourclass.class));

只是一个快速的想法,不确定它是否会起作用。

【讨论】:

  • 同样值得注意的是,如果你走这条路,这个类甚至根本不需要是一个实体(可以说提问者的类不是,因为它实际上似乎并不映射到表格)
  • 这个类确实映射到一个表。但我想弄清楚的是如何使具有额外派生字段的表映射到我可以返回到前端的对象。
猜你喜欢
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2012-06-27
  • 2019-12-06
  • 1970-01-01
相关资源
最近更新 更多