由于 Hibernate Mapping 需要将某些字段设置为 @Transient 但 JSP 无权访问它们

Posted

技术标签:

【中文标题】由于 Hibernate Mapping 需要将某些字段设置为 @Transient 但 JSP 无权访问它们【英文标题】:Because of Hibernate Mapping need to have some of the fields as @Transient but JSP does not have access to them 【发布时间】:2015-06-22 09:15:12 【问题描述】:

在 Java 中,我可以访问类的瞬态字段的值。但是,我无法访问 JSP 上的相同字段。如何使它们对 JSP 可用?

我正在使用 Hibernate 检索值,我认为解决方案是 Transformers.aliasToBean 选项,但还有其他解决方案吗?

是否有摆脱瞬态注释但在 Hibernate 中具有相同映射的方法?那样的话,问题就迎刃而解了。

@AssociationOverrides(
        @AssociationOverride(name = "tta.names", joinColumns = @JoinColumn(name = "id")))
public class Names implements java.io.Serializable 

    private static final long serialVersionUID = -30956546435023625398L;

    @EmbeddedId
    private TableToAssociate tta = new TableToAssociate();


    @Transient
    public String getid() 
        return tta.getMyIds().getId();
    

    public void setid(String id) 
        this.tta.getMyIds().setId(id);
    

在 Java 中,我可以使用以下代码访问它们

     System.out.println(mystudents.getNames().iterator().next().getId());

在 JSP 中,我无法访问它们!

    <c:forEach var="nm"items="$mystudents.names">
                    $nm.id
                </c:forEach>

如果我输入另一个不是瞬态的名称字段,JSP 会成功显示该项目的值。

【问题讨论】:

您发布的代码中的transient field在哪里? 瞬态字段的全部意义在于它不受 Hibernate 管理。它的值不会被持久化、保存并且无法检索,因为它不应该进入数据库。具体见here @Daniel,请检查并修复 'public String getid()' 的拼写错误 [我希望 'getId()'] 此外,您应该提供更多详细信息,因为您写的内容似乎不可能。例如尝试检查 JSP 中的脚本: 具有完全限定的类名 亲爱的@Daniel,如果想解决您的问题,您必须更好地合作。您可能犯了一个拼写错误:例如是 getid(小写)。两天前我问你检查它,你忽略它。下面 Vlad Mihalcea 花了他的时间并根据拼写错误恕我直言准备答案。您被多次告知问题与 Hibernate Transient 无关,但您仍在挖掘该领域。我怀疑您错误地使用了 java.beans.Transient 注释。我请你证实这一点。非常简单的验证,但你也忽略了它。您通过赏金鼓励社区:请让我们帮助您并更好地合作 @michaldo 对于延迟我真的很抱歉我的系统出现问题无法启动它。会尽快更新你。再次对造成的任何不便表示歉意。 【参考方案1】:

尝试重命名方法以匹配 JavaBean 规范。

代替:

@Transient
public String getid() 
    return tta.getMyIds().getId();


public void setid(String id) 
    this.tta.getMyIds().setId(id);

你应该有:

@Transient
public String getId() 
    return tta.getMyIds().getId();


public void setId(String id) 
    this.tta.getMyIds().setId(id);

【讨论】:

【参考方案2】:

删除您实体上的@Transient。根据您的嵌入 ID,您选择了字段注释。您应该能够拥有一个吸气剂,Hibernate 不会在没有明确标记的情况下尝试持续存在。并更改 getter/setter 以使用正确的 JavaBean 语法。 getId 而不是 getid

【讨论】:

【参考方案3】:

这是因为transient 关键字停止了要序列化的字段。要将对象传递给 JSP,必须对其进行序列化。该字段不会出现在您的序列化对象中,因此它对 JSP 不可用。

为了解决您的问题,您应该看到 James 的评论以使用 @Transient 注释。它由 JPA 提供,它应该允许您不将值保存在 DB 中,而是将其序列化以便您的 JSP 可以使用它。

【讨论】:

谢谢,我知道这是因为瞬态注释但是如何解决这个问题,由于休眠我需要保持它们瞬态。 由于您不能直接执行此操作,因此您应该使用该字段的值创建一个新的 String 对象,并将您的对象传递给 JSP。在那里,您还传递了这个新的字符串对象并在您的 JSP 中使用它。 如果它解决了您的问题,请记得将其标记为答案。 感谢您的回答,我正在等待是否有更好的解决方案(与休眠相关),否则肯定会接受您的回答。 " 要将对象传递给 JSP,必须对其进行序列化" 这简直是假的。答案应该被删除【参考方案4】:

你问的是不可能的。就像我之前说的那样聪明。

@Transient 只是说不要序列化/反序列化。 Hibernate 不会序列化这个,jsp bean 也是如此。

你可以做几件事:

    我认为最好的办法是将字段包装在 bean 中的 getter 和 setter 中。这样您将在 bean 上设置属性,如果只有一个字段,则其他解决方案都会产生开销。
public class Bean() 
private Names name;
private String id;
public Bean() 
     //few action to load name
     this.id = name.getid();

public String getId() 
    return this.id;

    为 ui(Bean) 和 DB(Hibernate) 创建不同的实体。很多情况下 ui 层和实体并不相同,有时不应该耦合 您可以在休眠实体和 ui 层(Jsp bean)中使用继承并创建不同的实现

如果你问我,我认为最好的方法是在第 1 部分做。如果这种情况发生得更多,你应该考虑将你的 ui 层和业务实体解耦。

【讨论】:

以上是关于由于 Hibernate Mapping 需要将某些字段设置为 @Transient 但 JSP 无权访问它们的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate @OneToMany Mapping 获取记录

hibernate.cfg.xml 中如何设置 hbm.xml 和 Annotations 的 mapping

IDEA + SSH OA 第一天(Hibernate : Mapping (RESOURCE) not found)

org.hibernate.MappingException:无法确定类型:java.util.List,在表:用户,列:[org.hibernate.mapping.Column(事件)]

Hibernate 数据库方言配置;no dialect mapping for jdbc type:-9;生僻字

org.hibernate.MappingException:无法确定类型:java.util.Set,表:USERS,列:[org.hibernate.mapping.Column(invoices