gpt4 book ai didi

java - 有时java枚举是一个字符串

转载 作者:行者123 更新时间:2023-11-30 07:53:33 24 4
gpt4 key购买 nike

我们在 Wildfly 8.0.0 服务器上运行 JAVA Web 应用程序。我们有一个电子邮件模板编辑器表单,它使用 Mustache Fields 将一些可变数据放入模板中。邮件还有一个枚举字段,用于指定模板的类型。实体结构是这样的:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING, length = 255)
@DiscriminatorOptions(force = true)
@DiscriminatorValue("MailTemplate")
@Table(name = "MailTemplate")
public abstract class MailTemplate extends MyAbstractEntity // AbstractEntity holds the common id field for all entities
{
private String body;
private String subject;
}

public class CustomMailTemplate extends MailTemplate implements java.io.Serializable {
@Enumerated(EnumType.STRING)
@Column(name = "templateType")
private CustomTemplateType templateType;
}

public enum CustomTemplateType implements java.io.Serializable {
OneTemplateType,
AnotherTemplateType,
AndAThirdOneTemplateType
}

我们使用 JPA 将实体持久保存到 Oracle 数据库中。这是处理各种类型的模板的 Controller 结构:

public abstract class AbstractMailTemplateEditController<T extends MailTemplate, TYPE> {
@Getter @Setter
protected T entity;

@Getter @Setter
protected String subject;

@Getter @Setter
protected String body;

@Getter @Setter
protected TYPE templateType;
}

public class CustomMailTemplateEditController extends AbstractMailTemplateEditController<CustomMailTemplate, CustomTemplateType> implements Serializable {
// this is in a service which injected, it's just for the code example
@PersistenceContext
private EntityManager em;

public void saveTemplate(){
// let's assume now that our entity property exists
entity.setBody(body);
entity.setSubject(subject);
entity.setTemplateType(templateType); // SOMETHING WRONG HAPPENS HERE!
em.merge(entity);
}
}

这是非常奇怪的部分:

服务器重新启动后,我们可以毫无问题地保存模板。经过“T”时间后,我们无法保存模板,并且收到以下错误消息:

java.lang.String cannot be cast to CustomTemplateType

我开始调试它,在 entity.setTemplateType(templateType); 行中我看到 templateType 是一个 String,但是这个仅在服务器重新启动后一段时间后发生。在同一位置重新启动后,templateTypeCustomTemplateType,我可以保存模板。这是怎么发生的以及我该如何解决这个问题?

更新:根据 Tobias Liefke 的回答,我检查了如何在 View 中使用此 Controller ,并发现了以下内容:

<h:selectOneMenu value="#{bean.templateType}" styleClass="form-control" id="template-type" >
<f:selectItems value="#{bean.mailTemplateTypes}" var="item" itemLabel="#{msg[item]}" itemValue="#{item}" />
<f:selectItem itemLabel="Special template" itemValue="#{null}" />
</h:selectOneMenu>

#{bean.mailTemplateTypes} 是一个枚举列表。那么这可能是一个 JSF bug 吗?我的意思是一段时间后(几天、几周没有服务器重新启动)JSF 开始将选定的 mailTemplateType 作为 String 传递到 #{bean.templateType}值。是否可以?我检查了这个问题:How to use enum values in f:selectItem(s)根据 BalusC 的回答,JSF 有一个内置的 enum 转换器。但这是我们设置 templateType 变量的唯一部分。

最佳答案

问题是未绑定(bind)的<TYPE> ,它将被编译为 protected Object templateType;public void setTemplateType(Object templateType)

您的应用程序中有人正在调用 setTemplateType()String 。如果他使用反射(如 Mustache Fields 所做的那样)或使用未绑定(bind)的 AbstractMailTemplateEditController,这是可能的。 .

如果 AbstractMailTemplateEditController 的所有子类使用 TYPE 的枚举,您可以将其绑定(bind)到 Enum :

public abstract class AbstractMailTemplateEditController<T extends MailTemplate, TYPE extends Enum<TYPE>> {

这将导致public void setTemplateType(Enum<?> templateType)在类文件中 - 这将抛出 ClassCastException一旦有人用 String 调用它.

否则你可以覆盖setTemplateTypeCustomMailTemplateEditController并进行显式类型检查:

public class CustomMailTemplateEditController ... {
@Override
public void setTemplateType(CustomTemplateType templateType) {
super.setTemplateType(templateType);
}
}

关于java - 有时java枚举是一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32997361/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com