首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >胸腺嘧啶结合集合

胸腺嘧啶结合集合
EN

Stack Overflow用户
提问于 2015-05-24 12:26:45
回答 3查看 3.5K关注 0票数 2

我在使用spring和thymeleaf绑定集合时遇到了问题。每次发送表单时,对象集合都被设置为null (User.postions),下面是我的示例:

我的财务主任:

代码语言:javascript
复制
@RequestMapping(value = urlFragment + "/add", method = RequestMethod.GET)
public String addPosition(Model model) {

    HashSet<Position> positions = new HashSet<Position>(positionRepository.findByEnabledTrueOrderByNameAsc());

    User employee = new User();

    for (Position position : positions) {
        employee.addPosition(position);
    }

    model.addAttribute("employee", employee);

    return "crud/employee/add";
}

@RequestMapping(value = urlFragment + "/add", method = RequestMethod.POST)
public String processNewEmployee(Model model, @Valid @ModelAttribute("employee") User employee, BindingResult result) {
    String templatePath = "crud/employee/add";

    if (!result.hasErrors()) {
        userRepository.save(employee);
        model.addAttribute("success", true);
    }

    return templatePath;
}

我的雇员表格:

代码语言:javascript
复制
<form action="#" th:action="@{/panel/employee/add}" th:object="${employee}" method="post">

    <div class="row">
        <div class="col-md-6">
            <label th:text="#{first_name}">First name</label>
            <input class="form-control" type="text" th:field="*{userProfile.firstName}"/>
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            <label th:text="#{last_name}">Last name</label>
            <input class="form-control" type="text" th:field="*{userProfile.lastName}"/>
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            <label th:text="#{email}">Email</label>
            <input class="form-control" type="text" th:field="*{email}"/>
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            <label th:text="#{position}">Position</label>
            <select th:field="*{positions}" class="form-control">
                <option th:each="position : *{positions}"
                        th:value="${position.id}"
                        th:text="${position.name}">Wireframe
                </option>
            </select>
        </div>
    </div>


    <div class="row">
        <div class="col-md-5">
            <div class="checkbox">
                <button type="submit" class="btn btn-success" th:text="#{add_employee}">
                    Add employee
                </button>
            </div>
        </div>
    </div>
</form>

用户实体:

代码语言:javascript
复制
@Entity
@Table(name="`user`")
public class User extends BaseModel {

    @Column(unique = true, nullable = false, length = 45)
    private String email;

    @Column(nullable = false, length = 60)
    private String password;

    @Column
    private String name;

    @Column
    private boolean enabled;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "user_role",
            joinColumns = {@JoinColumn(name = "user_id", nullable = false)},
            inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false)}
    )
    private Collection<Role> roles = new HashSet<Role>();

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "user_position",
            joinColumns = {@JoinColumn(name = "user_id", nullable = false)},
            inverseJoinColumns = {@JoinColumn(name = "position_id", nullable = false)}
    )
    private Collection<Position> positions = new HashSet<Position>();

    public User() {
    }

    public User(String email, String password, boolean enabled) {
        this.email = email;
        this.password = password;
        this.enabled = enabled;
    }

    public User(String email, String password, boolean enabled, Set<Role> roles) {
        this.email = email;
        this.password = password;
        this.enabled = enabled;
        this.roles = roles;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Collection<Position> getPositions() {
        return positions;
    }

    private void setPositions(Collection<Position> positions) {
        this.positions = positions;
    }

    public boolean addPosition(Position position) {
        return positions.add(position);
    }

    public boolean removePosition(Position position) {
        return positions.remove(position);
    }

    public Collection<Role> getRoles() {
        return roles;
    }

    private void setRoles(Collection<Role> roles) {
        this.roles = roles;
    }

    public boolean addRole(Role role) {
        return roles.add(role);
    }

    public boolean removeRole(Role role) {
        return roles.remove(role);
    }

    @Override
    public String toString() {
        return User.class + " - id: " + getId().toString() + ", email: " + getEmail();
    }
}

我在某个地方读到了必须创建equals()和hashCode()的内容,所以我在我的位置实体中这样做了。

代码语言:javascript
复制
public boolean equals(Position position) {
    return this.getId() == position.getId();
}

public int hashCode(){
    return this.getId().hashCode() ;
}

以下是用post方法发送的数据:

以下是我的研究结果:

我的春季版本:4.1.6.dialect- spring 4版本:2.1.4.dialect-布局-方言版本: 1.2.8

当然,我希望位置是HashCode,有一个id = 2的物体位置元素,你能帮我吗?我做错什么了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-11 19:42:34

谢谢各位回答我的问题。你帮了我很多。不幸的是,我不得不在一件事上不同意你的观点。你给我举了一个例子:

代码语言:javascript
复制
newPosition.setId(position.getId());

安德鲁 github存储库中也有相同的例子。我认为使用setId()方法是错误的做法。因此,我将提出我的解决方案,我将等待一些意见,然后我将它标记为一个答案。

WebMvcConfig类

代码语言:javascript
复制
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.smartintranet")
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @PersistenceContext
    private EntityManager entityManager;

    // (....rest of the methods.......)

    @Override
    public void addFormatters(FormatterRegistry formatterRegistry) {
        formatterRegistry.addFormatter(new PositionFormatter(entityManager));
    }
}

PositionFormatter类

代码语言:javascript
复制
public class PositionFormatter implements Formatter<Position> {

    private EntityManager entityManager;

    public PositionFormatter(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public String print(Position position, Locale locale) {
        if(position.getId() == null){
            return "";
        }

        return position.getId().toString();
    }

    public Position parse(String id, Locale locale) throws ParseException {
        return entityManager.getReference(Position.class, Long.parseLong(id));
    }
}

employeeForm.html

代码语言:javascript
复制
                <div class="col-md-6">
                    <label th:text="#{position}">Position</label>
                    <select th:field="*{position}" class="form-control">
                        <option th:each="position : ${allPositions}"
                                th:value="${position.id}"
                                th:text="${position.name}">Wireframe
                        </option>
                    </select>
                </div>

和最后一个,EmployeeController类

代码语言:javascript
复制
@Controller
public class EmployeeController extends AbstractCrudController {    
    // (...rest of dependency and methods....)

    @Transactional
    @RequestMapping(value = urlFragment + "/create", method = RequestMethod.GET)
    public String createNewEmployee(Model model) {
        prepareEmployeeForm(model);
        return "crud/employee/create";
    }

    @Transactional
    @RequestMapping(value = urlFragment + "/create", method = RequestMethod.POST)
    public String processNewEmployee(Model model, @ModelAttribute("employee") Employee employee, BindingResult result) {
        if (!result.hasErrors()) {
            // Look here it is important line!
            entityManager.merge(employee.getUser());
        }

        prepareEmployeeForm(model);

        return "crud/employee/create";
    }
}

这是我的解决办法。这里有什么不好的?我想这句话是:

代码语言:javascript
复制
entityManager.merge(employee.getUser());

我不能在这里用:

代码语言:javascript
复制
userRepository.save(employee.getUser());

因为位置实体是分离的,当我使用保存方法时,它在这种情况下运行em.persist(),所以我手动运行em.merge()。我知道这段代码并不完美,但我认为这个解决方案比使用setId()更好。我将感谢建设性的批评。

再一次感谢安德鲁布莱泽没有你的帮助,我不会这么做的。我把你的答案标为有用的。

票数 0
EN

Stack Overflow用户

发布于 2015-06-28 16:42:23

这是因为您使用${position.id}作为您的选项值。这意味着spring无法计算值中使用的id与实际位置对象之间的关系。试着用${position}来表示您的价值,它应该可以工作:

代码语言:javascript
复制
                    <select th:field="*{positions}" class="form-control">
                        <option th:each="position : *{positions}"
                                th:value="${position}"
                                th:text="${position.name}">Wireframe
                        </option>
                    </select>

(确保您已经实现了hashCode并在您的位置类上实现了等号)

如果这仍然不起作用,您可能必须实现一个格式化程序的位置,以使转换显式。参见下面的示例胸腺瘤样例.选择倍数

票数 1
EN

Stack Overflow用户

发布于 2015-06-29 12:09:17

通过向MVC的配置添加格式化程序类和添加格式化程序,我也解决了类似的问题:

代码语言:javascript
复制
@Override
protected void addFormatters(FormatterRegistry registry){
    registry.addFormatter(new PositionFormater());
    ...
}

位置类格式化程序应该如下所示:

PositionFormatter:

代码语言:javascript
复制
public class PositionFormatter implements Formatter<Position>{

/** String representing null. */
private static final String NULL_REPRESENTATION = "null";

@Resource
private PositionRepository positionRepository;

public PositionFormatter() {
    super();
}

@Override
public String print(Position position, Locale locale) {
    if(position.equals(NULL_REPRESENTATION)){
        return null;
    }
    try {
        Position newPosition = new Position();
        newPosition.setId(position.getId());
        return newPosition.getId().toString();
    } catch (NumberFormatException e) {
        throw new RuntimeException("Failed to convert `" + position + "` to a valid id");
    }

}

@Override
public Position parse(String text, Locale locale) throws ParseException {
    if (text.equals(NULL_REPRESENTATION)) {
        return null;
    }
    try {
        Long id = Long.parseLong(text);
        Position position = new Position();
        position.setId(id);
        return position;
    } catch (NumberFormatException e) {
        throw new RuntimeException("Failed to convert `" + text + "` to valid Position");
    }
  }
}

就我而言,这两个人解决了所有问题。我有几个格式化程序,我所做的就是把它添加到配置文件中(在我的例子中是WebMVCConfig)。

查看我解决这个问题的原稿。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30423478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档